2016-09-29 4 views
-3

Я пытаюсь создать приложение на основе сокета. Глядя на консоль, можно сказать, что клиент дважды пытается подключиться к серверу сокетов; которые не должны допускаться.Отдельный объект сокета IO

  1. Есть ли способ остановить это?
  2. Если у вас есть модульный файл javascript, где несколько сценариев хотят получить доступ к одному и тому же соединению сокетов, как это возможно?

<!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>

ответ

0
  1. Не подключайте клиента дважды сокет ....

  2. Глобальная переменная позволит вам получить доступ к сокет из всех вашего сценария файлы

Например)

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

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

Обратите внимание, что в JavaScript загрязняют глобальную область с переменными и функциями считается плохой практикой, но это для другой должности.

+0

поэтому решение приходит, чтобы создать фабрику, которая будет синглтон для io .. если не ошибаюсь – Rastafari

0

Очевидное предложение состоит в том, чтобы остановить подключение вашего клиента дважды.

Но если вы пытаетесь предотвратить несколько подключений на сервере, и вы действительно не хотите, чтобы какой-либо конечный пользователь мог использовать несколько окон за раз на вашем веб-сайте, тогда вы можете предотвратить другое когда соединение уже установлено.

Ключ должен идентифицировать каждый браузер с каким-то уникальным cookie (идентификатором пользователя или уникально сгенерированным идентификационным номером). Затем вы можете реализовать аутентификацию socket.io, которая отслеживает, какие идентификаторы пользователей уже имеют соединение, и если соединение уже работает, последующие попытки подключения не пройдут этап аутентификации и будут отключены.

Предполагается, что у вас есть набор файлов cookie для каждого браузера, который называется userId. Тогда, вот пример приложения, которое удостоверяется идента печенье присутствует, а затем использует его, чтобы запретить подключение более чем один socket.io:

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. Вам действительно нужно подумать о ситуации, когда пользователь с несколькими компьютерами (например, домашний/рабочий) оставляет один компьютер и открывает вашу страницу и, таким образом, подключается через socket.io, а затем пытается подключить ваш сайт с другого компьютера. Если вы отказались от второго соединения, это не позволит им получить доступ со своего второго компьютера, если первый компьютер оказался открытым и включенным.

+0

Добавлен пример кода, который отрицает более одного подключения socket.io для каждого браузера. – jfriend00

+0

@ Rastafari - Так работает ли этот код для вас? – jfriend00

+0

На самом деле, если у меня есть структура плагинов компонентов вида, где два или более плагинов хотят получить доступ к службе сокетов, то если сокет уже подключен, я хочу использовать существующее соединение еще, я хочу создать новое соединение. – Rastafari

Смежные вопросы