2016-09-29 62 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. 一个全局变量将允许您从您的所有脚本访问套接字文件

EG)

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

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

注意,在JavaScript污染与变量被认为是不好的做法功能在全球范围内,但这是另一篇文章。

+0

因此该解决方案来创建一个工厂,会在IO单身..如果我没看错 – Rastafari

0

明显的建议是停止让客户端连接两次。

但是,如果你想防止服务器上的多个连接,你真的不希望任何最终用户能够同时使用多个窗口到您的网站,那么你就可以防止其他连接一旦已经有连接。

的关键将是确定与某种独特的cookie(用户ID或唯一地生成的ID号)的各个浏览器。然后,您可以实施socket.io身份验证,以跟踪哪些用户ID已经拥有连接,并且如果连接已经处于活动状态,那么随后的连接尝试将失败身份验证步骤并断开连接。

认为你必须为每一个被称为userId浏览器设置Cookie。那么,这里是一个示例应用程序,使确保userid cookie的存在,然后用它来否定一个以上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); 
    }); 
}); 

附:你必须仔细考虑一下,如果用户拥有多台计算机(比如家庭/办公室),将一台计算机留在网页上并打开你的页面,并通过socket.io连接,然后尝试从另一台计算机上使用你的网站。如果您拒绝第二次连接,如果第一台计算机发生打开和打开,这将拒绝他们从第二台计算机访问。

+0

否认每个浏览器多个socket.io连接添加示例代码。 – jfriend00

+0

@Rastafari - 这个代码对你有用吗? – jfriend00

+0

其实如果我有两个或多个插件想要访问套接字服务的视图组件的插件结构,那么如果套接字已经连接,那么我想使用现有的连接,否则我想创建一个新的连接。 – Rastafari