客户端断开连接时出现node.js错误

时间:2017-05-02 05:08:42

标签: node.js server socket.io

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

Error I'm getting

这是我的代码

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);
}

1 个答案:

答案 0 :(得分:0)

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

不使用客户端上的socket.emit('logout', username)事件,而是使用内置的注销事件,当用户关闭浏览器时会触发该事件。那个事件是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")
  });
});