【问题标题】:node.js error upon client disconnect客户端断开连接时的node.js错误
【发布时间】:2017-09-29 12:57:05
【问题描述】:

我正在使用 node.js,每次客户端断开连接时都会出现图片中的错误(当我关闭选项卡时会发生这种情况,并且我还尝试在客户端和客户端上使用 socket.disconnect()服务器端)

这是我的代码

var io = require('socket.io').listen(4000);
var fs = require('fs');

io.sockets.on('connection', function(socket) {
  socket.on('login', function(info)
  {
      fs.readFile("chatLog.txt", function(err, data)
      {
          if(err)
          {
              return console.error(err);
          }
          socket.emit('incomingMessage', data.toString());
      });
      socket.broadcast.emit('newUser', info);
  });
  socket.on('message', function(content) {
    console.log(content); 
    io.sockets.emit('incomingMessage', content);
  });
  socket.on('logout', function(name)
  {
     socket.broadcast.emit('incomingMessage', "user: " + name + " has logged out");
     //socket.disconnect();
  });
});

谁能告诉我如何在不导致服务器因该错误而崩溃的情况下断开连接?

客户端 HTML:

<html>
<head>
<!-- This is the websocket SERVER -->
<script src="http://localhost:4000/socket.io/socket.io.js"></script>
<script src="client.js"></script>

</head>
<body>
<div id="loginDiv">
    username: <input type="text" id = "userName"><br>
    <input type = "button" id="login" value = "login" onClick="login()">
</div>
<div id="logoutDiv" style="visibility:hidden">
    <input type = "button" id = "messageRedir" value = "send message" onClick= "gotoMessage()">
    <input type = "button" id = "logout" value = "logout" onClick="logout()">
</div>
<div id="sendMessage" style="visibility:hidden">
    <input type = "text" id="messageBox"><br>
    <input type = "button" value="send message" onClick="sendMessage()">
    <input type = "button" value = "cancel" onClick="back">
</div>
<div id="msg"></div> 
</body> 
</html>

客户端JS:

var userName = null;
var socket = null;
function login()
{

  socket = io.connect('http://localhost:4000');
  userName = document.getElementById('userName').value;
  document.getElementById("loginDiv").style.visibility = "hidden";
  document.getElementById("logoutDiv").style.visibility = "visible";
  socket.emit('login', userName+ ' has connected');

  // Attach event handler for event fired by server
  socket.on('incomingMessage', function(data) {
     var elem = document.getElementById('msg'); 
     console.log(data);
     elem.innerHTML =  data + "<br>" + elem.innerHTML; // append data that we got back
  });
   socket.on('newUser', function(data) {
     var elem = document.getElementById('msg'); 
     console.log(data);
     elem.innerHTML =  data + "<br>" + elem.innerHTML; // append data that we got back
  });
}

function logout()
{
    document.getElementById("loginDiv").style.visibility = "visible";
    document.getElementById("logoutDiv").style.visibility = "hidden";
    document.getElementById('msg').innerHTML = "";
    socket.emit('logout', userName);
    socket.disconnect();
    socket = null;
}

function gotoMessage()
{
    document.getElementById("loginDiv").style.visibility = "hidden";
    document.getElementById("msg").style.visibility = "hidden";
    document.getElementById("sendMessage").visibility = "visible";
}

function back()
{
    document.getElementById("loginDiv").style.visibility = "visible";
    document.getElementById("msg").style.visibility = "visible";
    document.getElementById("sendMessage").visibility = "hidden";
}

function sendMessage()
{
    var mess = document.getElementById('messageBox').value;
    socket.emit('message', mess);
}

【问题讨论】:

  • 你能给我们看看客户端代码吗?
  • 我已经编辑了帖子,以便它现在显示客户端代码

标签: node.js server socket.io


【解决方案1】:

问题很可能出在您使用套接字(不再处于活动状态)发出事件的注销功能中。您应该改用io.sockets.emit。我有一些建议。

不要在客户端使用socket.emit('logout', username) 事件,而是使用用户关闭浏览器时触发的内置logout 事件。该事件是disconnect。您也不需要在每个请求中传递用户名。您只需要通过登录事件传递一次。然后您可以将用户名作为套接字的属性存储在服务器上。

客户端

function login()
{

  socket = io.connect('http://localhost:4000');
  userName = document.getElementById('userName').value;
  document.getElementById("loginDiv").style.visibility = "hidden";
  document.getElementById("logoutDiv").style.visibility = "visible";
  // just send the username
  socket.emit('login', userName);

  // Attach event handler for event fired by server
  socket.on('incomingMessage', function(data) {
     var elem = document.getElementById('msg'); 
     console.log(data);
     elem.innerHTML =  data + "<br>" + elem.innerHTML; // append data that we got back
  });
   socket.on('newUser', function(data) {
     var elem = document.getElementById('msg'); 
     console.log(data);
     elem.innerHTML =  data + "<br>" + elem.innerHTML; // append data that we got back
  });
}

function logout()
{
    document.getElementById("loginDiv").style.visibility = "visible";
    document.getElementById("logoutDiv").style.visibility = "hidden";
    document.getElementById('msg').innerHTML = "";
    socket.disconnect();
    socket = null;
}

服务器端

io.sockets.on('connection', function(socket) {
  socket.on('login', function(uxname)
  {
      // store username variable as property of the socket connection
      // this way we can handle the disconnect message later
      this.username = uxname;

      fs.readFile("chatLog.txt", function(err, data)
      {
          if(err)
          {
              return console.error(err);
          }
          socket.emit('incomingMessage', data.toString());
      });
      socket.broadcast.emit('newUser', uxname);
  });
  socket.on('message', function(content) {
    console.log(content); 
    io.sockets.emit('incomingMessage', content);
  });
  socket.on('disconnect', function(){
       // don't use socket.broadcast.emit. at this point the socket is destroyed and you cant call events on it. That is most likely why you have the error.
       // use io.sockets.emit instead
       io.sockets.emit('incomingMessage', "user: " + this.username + " has logged out")
  });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    相关资源
    最近更新 更多