【问题标题】:node.js websocket crashes when client disconnect客户端断开连接时node.js websocket崩溃
【发布时间】:2014-06-20 11:39:02
【问题描述】:

我对@9​​87654323@ 和Websockets 很陌生,但我正在尝试使用它。

我所做的是从串行端口读取传入数据,然后使用 websocket 将这些数据发送到网页。 从这里一切正常。

  • 我使用node-static 提供我的网页
  • 我将ws 用于websocket

问题是当客户端关闭他的浏览器时,我的 NodeJS websocket 服务器崩溃并出现以下错误:

root@WS-SERVER-2:~/app# node socketserver.js
open serial communication
Client disconnected.

/root/node-v0.10.29/lib/node_modules/ws/lib/WebSocket.js:187
    else throw new Error('not opened');
               ^
Error: not opened
    at WebSocket.send (/root/node-v0.10.29/lib/node_modules/ws/lib/WebSocket.js:187:16)
    at sendAll (/root/app/socketserver.js:30:16)
    at SerialPort.<anonymous> (/root/app/socketserver.js:58:8)
    at SerialPort.emit (events.js:95:17)
    at Object.module.exports.raw [as parser] (/root/node-v0.10.29/bin/node_modules/serialport/parsers.js:8:13)
    at Object.SerialPort.options.dataCallback (/root/node-v0.10.29/bin/node_modules/serialport/serialport.js:143:15)
    at SerialPortFactory.SerialPort._emitData (/root/node-v0.10.29/bin/node_modules/serialport/serialport.js:312:20)
    at afterRead (/root/node-v0.10.29/bin/node_modules/serialport/serialport.js:290:18)
    at /root/node-v0.10.29/bin/node_modules/serialport/serialport.js:304:9
    at Object.wrapper [as oncomplete] (fs.js:459:17)

这是我的 websocket/serialport 代码:

var WebSocketServer = require('../node-v0.10.29/lib/node_modules/ws').Server;
var SerialPort = require('../node-v0.10.29/bin/node_modules/serialport').SerialPort;

var serialPort;
var portName = '/dev/ttyACM0';
var sendData = "";
var wss = new WebSocketServer({port: 8080});

var CLIENTS=[];

wss.on('connection', function(ws) {
       CLIENTS.push(ws);
    ws.on('message', function(message) {
        console.log('received: %s', message);
        sendAll(message);
    });
    ws.on('close', function() {
        console.log('Client disconnected.');
    });
    ws.on('error', function() {
        console.log('ERROR');
    });
    ws.send("");
});

function sendAll(message)
{
for(var i=0;i<CLIENTS.length;i++)
    {
    CLIENTS[i].send(message);
    }
}

serialListener();

function serialListener(debug)
{
    var receivedData = "";
    serialPort = new SerialPort(portName, {
        baudrate: 9600,
         dataBits: 8,
         parity: 'none',
         stopBits: 1,
         flowControl: false
    });

    serialPort.on("open", function () {
      console.log('open serial communication');
            // Listens to incoming data
        serialPort.on('data', function(data) {
             receivedData += data.toString();
          if (receivedData .indexOf('E') >= 0 && receivedData .indexOf('B') >= 0) {
           sendData = receivedData .substring(receivedData .indexOf('B') + 1, receivedData .indexOf('E'));
           receivedData = '';
         }
         // send the incoming data to browser with websockets.
       sendAll(sendData);
      });
    });
}

谁能帮我弄清楚这里出了什么问题?

【问题讨论】:

    标签: node.js websocket


    【解决方案1】:

    我认为,您应该在 closeerror 事件中从 CLIENTS 数组中删除套接字。否则,它会尝试向已关闭的套接字发送消息。

    【讨论】:

    • 看来你是对的,因为如果我在 close 事件上初始化我的数组,它就不会再崩溃了。但是,从现在开始,我正在寻找一种方法来识别断开连接的客户端以将其从数组中删除
    • 也许CLIENTS.splice(CLIENTS.indexOf(ws), 1)?
    • 太好了,工作!!将对此进行进一步调查(我正在学习......)。谢谢
    • 有时还是会崩溃...会在发生时尝试隔离上下文
    【解决方案2】:

    我遇到了同样的问题。结果我试图将事件发送到处于“关闭”状态的套接字。在广播消息之前检查每个套接字是否是专门打开的:

        function sendAll(data){
            for(var i = 0; i < clients.length; i++){
                if(this.clients[i].readyState != this.clients[0].OPEN){
                    console.error('Client state is ' + this.clients[i].readyState);
                }
                else{
                    this.clients[i].send(data);
                }
            }
        }
    

    【讨论】:

    • 官方文档像这样测试 readyState:if (this.clients[i].readyState === WebSocket.OPEN) 我认为这比针对第一个数组元素的属性进行测试更可取
    【解决方案3】:

    在向客户端发送数据时试试这个: - socket 是我当前的 Web 套接字对象。它会覆盖默认的 >WebSocket.js 类条件,该条件会引发“未打开错误”。

    if (socket.readyState != socket.OPEN) {
        console.error('Client state is ' + socket.readyState);
        //or any message you want
    } else {
        socket.send(JSON.stringify(object)); //send data to client
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 2017-09-29
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 2022-01-03
      相关资源
      最近更新 更多