2016-09-29 42 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