Nodejs - websocket-node模块:如何使多客户端套接字服务器工作?

时间:2015-10-06 02:51:21

标签: javascript node.js sockets websocket connection

我使用websocket模块创建了一个套接字服务器,此配置取自this example(有一些更改):

    var WebSocketServer = require('websocket').server;
var http = require('http');

var server = http.createServer(function(request, response) {
    console.log((new Date()) + ' Received request for ' + request.url);
    response.writeHead(404);
    response.end();
});
server.listen(5050, function() {
    console.log((new Date()) + ' Server is listening on port 5050');
});

wsServer = new WebSocketServer({
    httpServer: server,
    // You should not use autoAcceptConnections for production 
    // applications, as it defeats all standard cross-origin protection 
    // facilities built into the protocol and the browser.  You should 
    // *always* verify the connection's origin and decide whether or not 
    // to accept it. 
    autoAcceptConnections: false
});

function originIsAllowed(origin) {
  // put logic here to detect whether the specified origin is allowed. 
  return true;
}

wsServer.on('request', function(request) {
    if (!originIsAllowed(request.origin)) {
      // Make sure we only accept requests from an allowed origin 
      request.reject();
      console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
      return;
    }

    var connection = request.accept('echo-protocol', request.origin);
    console.log((new Date()) + ' Connection accepted.');
    connection.on('message', function(message) {
        if (message.type === 'utf8') {
            console.log('Received Message: ' + message.utf8Data);
            connection.sendUTF(message.utf8Data);
        }
        else if (message.type === 'binary') {
            console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
            connection.sendBytes(message.binaryData);
        }
    });
    connection.on('close', function(reasonCode, description) {
        console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
    });
});

我在html中创建自己的客户端:

<html>
    <head>
        <script src='./js/jquery1-11-3-min.js'></script>
        <script>
            $(document).ready(function (){
                buildwebsocket();
            });
            var ws;
            function buildwebsocket(){
                ws = new WebSocket("ws://192.168.0.96:5050",'echo-protocol');
                ws.onopen = function(evt) { onOpen(evt) };
                ws.onclose = function(evt) { onClose(evt) };
                ws.onmessage = function(evt) { onMessage(evt) };
                ws.onerror = function(evt) { onError(evt) };
            }
            function onOpen(ev){
                //alert("konek men! mantap! :D");
                $("#recmsg").append("connected!<br>");
            }
            function onClose(ev){
                $("#recmsg").append("connection closed!<br>");
            }
            function onMessage(ev){
                //alert("ada pesan datang!");
                $("#recmsg").append(ev.data+"<br>");
            }
            function onError(ev){
                $("#recmsg").append("connecting error!<br>");
            }
            function doSend(){
                //writeToScreen("SENT: " + message); 
                var message = $("#pesan").val();
                ws.send(message);
            } function doClose(){
                ws.close();
            }
            //function writeToScreen(message){
                //var pre = document.createElement("p");
                //pre.style.wordWrap = "break-word";
                //pre.innerHTML = message;
                //output.appendChild(pre);
            //}
            //window.addEventListener("load", init, false);
        </script>
    </head>
    <body>
        <button onclick='doClose()'>Close</button>
        <textarea id='pesan'></textarea><br>
        <button onclick='doSend()'>Kirim!</button>
        <br>
        received message
        <div id='recmsg'>
        </div>  
    </body>
</html>

客户端(第一个客户端)与服务器之间的连接已成功建立。我尝试从第一个客户端发送消息,然后服务器接收没有任何promblem的消息,然后将消息发送回第一个客户端,第一个客户端接收它。 我可以说连接和插座运行良好 我尝试建立另一个连接(第二个客户端),因此我在另一个设备中打开第二个客户端。连接很好。但是,当我从第一个或第二个客户端发送消息时,第一个客户端没有得到响应,但第二个客户端得到它
如果打开第三个客户端然后发送消息,则第一个和第二个客户端不会得到响应。 只有最后连接的客户端才会收到服务器的响应,并且没有客户端收到任何错误消息
它是模块的缺点吗?或者必须更改/添加服务器配置?
我可以使用此模块建立支持多客户端的套接字服务器吗?

2 个答案:

答案 0 :(得分:7)

您没有在服务器端存储连接。您只需在服务器上进行设置即可直接与服务器进行通信。如果您希望将发送到服务器的消息发送回所有人,则需要为服务器上的每个连接设置on.('message', ...)函数以获得该行为。为此,您需要在创建连接时存储连接。试试这个:

var WebSocketServer = require('websocket').server;
var http = require('http');

var server = http.createServer(function(request, response) {
    console.log((new Date()) + ' Received request for ' + request.url);
    response.writeHead(404);
    response.end();
});
server.listen(5050, function() {
    console.log((new Date()) + ' Server is listening on port 5050');
});

wsServer = new WebSocketServer({
    httpServer: server,
    // You should not use autoAcceptConnections for production 
    // applications, as it defeats all standard cross-origin protection 
    // facilities built into the protocol and the browser.  You should 
    // *always* verify the connection's origin and decide whether or not 
    // to accept it. 
    autoAcceptConnections: false
});

function originIsAllowed(origin) {
  // put logic here to detect whether the specified origin is allowed. 
  return true;
}

//create an array to hold your connections
var connections = [];

wsServer.on('request', function(request) {
    if (!originIsAllowed(request.origin)) {
      // Make sure we only accept requests from an allowed origin 
      request.reject();
      console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
      return;
    }
    var connection = request.accept('echo-protocol', request.origin);

    //store the new connection in your array of connections
    connections.push(connection);

    console.log((new Date()) + ' Connection accepted.');
    connection.on('message', function(message) {
        if (message.type === 'utf8') {
            console.log('Received Message: ' + message.utf8Data);

            //send the received message to all of the 
            //connections in the connection array
            for(var i = 0; i < connections.length; i++) {
                connections[i].sendUTF(message.utf8Data);
            }
        }
        else if (message.type === 'binary') {
            console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
            connection.sendBytes(message.binaryData);
        }
    });
    connection.on('close', function(reasonCode, description) {
        console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
    });
});

答案 1 :(得分:0)

细微的差别可能是将推送的索引存储为整数变量。 然后你可以在 on_close 将它从数组中拼接出来。 否则你的连接数组会无限增长。