2016-09-29 6 views
-3

Ich versuche, eine Anwendung basierend auf Socket zu erstellen. Betrachtet man die Konsole, kann man sagen, dass der Client versucht, den Server zweimal zu verbinden. was nicht erlaubt sein sollte.Einzelobjekt des Sockets IO

  1. Gibt es eine Möglichkeit, das zu stoppen?
  2. Wenn modulare JavaScript-Datei, wo mehrere Skripte auf die gleiche Socket-Verbindung zugreifen möchten, wie ist das möglich?

<!DOCTYPE html> 
 
<html> 
 
<head> 
 
\t <title>socket</title> 
 
\t <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> 
 
\t <script src="https://cdn.socket.io/socket.io-1.4.5.js"></script> 
 
</head> 
 
<body> 
 

 
<script type="text/javascript"> 
 
\t $(function(){ 
 
\t \t var socket = io(); 
 
\t \t console.log(typeof socket); // object 
 
\t \t var socket1 = io(); 
 
\t \t console.log(socket === socket1); // false 
 
\t }) 
 
</script> 
 
</body> 
 
</html>

Antwort

0
  1. Sie den Client nicht verbinden zweimal an Buchse ....

  2. Eine globale Variable können Sie die Steckdose aus allen Skript zugreifen Dateien

Eg)

//you can access this variable from all your scripts 
var socket; 

$(function(){  
    socket = io();  
    console.log(typeof socket); 
}) 

Beachten Sie, dass die globale Reichweite mit Variablen und Funktionen in Javascript verschmutzenden ist schlechte Praxis betrachtet, aber das ist für einen anderen Posten.

+0

so kommt die Lösung, um eine Fabrik zu schaffen, die ein Singleton für io .. wenn ich nicht falsch bin – Rastafari

0

Der offensichtliche Vorschlag besteht darin, die Verbindung Ihres Clients zweimal zu beenden.

Wenn Sie jedoch mehrere Verbindungen auf dem Server verhindern möchten und nicht möchten, dass ein Endbenutzer mehr als ein Fenster gleichzeitig auf Ihrer Website verwenden kann, können Sie ein anderes verhindern Verbindung, sobald bereits eine Verbindung besteht.

Der Schlüssel wäre, jeden Browser mit einer Art eindeutigem Cookie zu identifizieren (Benutzer-ID oder eindeutig generierte ID-Nummer). Sie können dann die socket.io-Authentifizierung implementieren, die verfolgt, welche Benutzer-IDs bereits eine Verbindung haben, und wenn eine Verbindung bereits aktiv ist, scheitern nachfolgende Verbindungsversuche beim Authentifizierungsschritt und werden getrennt.

Angenommen, Sie haben für jeden Browser einen Cookie gesetzt, der userId heißt. Dann ist hier eine Beispielanwendung, die die Benutzer-ID-Cookie stellt sicher, vorhanden ist und dann verwendet er mehr als eine socket.io Verbindung zu verweigern:

const express = require('express'); 
const app = express(); 
const cookieParser = require('cookie-parser'); 
const cookie = require('cookie'); 

app.use(cookieParser()); 

let userIdCntr = 1; 
const tenDays = 1000 * 3600 * 24 * 10; 

app.use(function(req, res, next) { 
    // make sure there's always a userId cookie 
    if (!req.cookies || !req.cookies.userId) { 
     // coin unique user ID which consists of increasing counter and current time 
     let userId = userIdCntr++ + "_" + Date.now(); 
     console.log("coining userId: " + userId); 
     res.cookie('userId', userId, { maxAge: Date.now() + tenDays , httpOnly: true }); 
    } 
    next(); 
}); 

app.get('/test.html', function (req, res) { 
    console.log('Cookies: ', req.cookies) 
    res.sendFile(__dirname + "/" + "test.html"); 
}); 

const server = app.listen(80); 
const io = require('socket.io')(server); 

// which users are currently connected 
var users = new Set(); 

// make sure cookie is parsed 
io.use(function(socket, next) { 
    if (!socket.handshake.headers.cookieParsed) { 
     socket.handshake.headers.cookieParsed = cookie.parse(socket.handshake.headers.cookie || ""); 
    } 
    next(); 
}); 

// now do auth to fail duplicate connections 
io.use(function(socket, next) { 
    console.log("io.use() - auth"); 
    // if no userId present, fail the auth 
    let userId = socket.handshake.headers.cookieParsed.userId; 
    if (!userId) { 
     next(new Error('Authentication error - no userId')); 
     return; 
    } 
    // if already logged in 
    if (users.has(userId)) { 
     console.log("Failing user " + userId); 
     next(new Error('Authentication error - duplicate connection for this userId')); 
     return; 
    } else { 
     console.log("adding user " + userId); 
     users.add(userId); 
    } 
    next(); 

}); 

io.on('connection', function(socket) { 
    console.log("socket.io connection cookies: ", socket.handshake.headers.cookieParsed); 

    socket.on('disconnect', function() { 
     console.log("socket.io disconnect"); 
     let userId = socket.handshake.headers.cookieParsed.userId; 
     users.delete(userId); 
    }); 

    // test message just to see if we're connected 
    socket.on("buttonSend", function(data) { 
     console.log("buttonSend: ", data); 
    }); 
}); 

P. S. Sie müssen wirklich die Situation durchdenken, in der ein Benutzer mit mehr als einem Computer (wie zu Hause/Arbeit) einen Computer an und öffnen Sie Ihre Seite und damit über socket.io verbunden und dann versucht, Ihre Website von dem anderen Computer zu verwenden. Wenn Sie die zweite Verbindung ablehnen, verweigern Sie ihnen den Zugriff von ihrem zweiten Computer aus, wenn der erste Computer zufällig offen gelassen wurde.

+0

Hinzugefügt Beispielcode, der mehr als eine socket.io Verbindung pro Browser verweigert. – jfriend00

+0

@Rastafari - funktioniert dieser Code für Sie? – jfriend00

+0

Eigentlich, wenn ich plugin Struktur von View-Komponenten, wo zwei oder mehr Plugins auf Socket-Dienst zugreifen möchten, wenn der Socket bereits verbunden wurde, dann möchte ich die vorhandene Verbindung verwenden, sonst möchte ich eine neue Verbindung erstellen. – Rastafari