【问题标题】:Display the username of a user who disconnects from the server显示与服务器断开连接的用户的用户名
【发布时间】:2020-08-17 05:48:47
【问题描述】:

当用户与服务器断开连接时,我正在尝试显示一条消息。它目前的工作原理是它将向所有连接的用户显示消息。但是,如果我尝试使用 user 变量来显示哪个用户已断开连接,它会向自己显示已连接客户端的名称,而不是离开的实际用户。我已经尝试了几件事,但无法让它发挥作用,这就是我想出的。 在浏览器中,当有人断开连接时,将显示以下代码“undefined has left the chat”。

如何更正此问题以显示实际用户名?

在 script.js 中:

var user = user;
if (!user) {
  user = prompt('Please choose a username:');
  if (!user) {
    alert('Your name has been set to "Anonymous"');
  } else {
      alert('Your name has been set to "'+ user +'"');
  } 
}

socket.emit('user disconnected', {
    user: user
  });

socket.on('user disconnected', (data) => {
      $('.chat').append(data.user + " has left the chat");
    });

在 server.js 中:

server(socket('disconnect', ctx => { console.log(ctx.data); ctx.io.emit('user disconnected', ctx.data); }));

此外,一旦用户断开连接,“传输关闭”就会发布到控制台,我不确定这意味着什么。

【问题讨论】:

    标签: javascript node.js express server socket.io


    【解决方案1】:

    你很接近。我为您的示例编写了以下代码。实际上,这将比添加数据库或使用一些会话存储有很多不同。

    下面是server.js

    const app = require('http').createServer(handler);
    const io = require('socket.io')(app);
    const fs = require('fs');
    
    const userIdMap = {};
    
    app.listen(3000);
    
    function handler(req, res) {
      fs.readFile(__dirname + '/test.html', function (err, data) {
        if (err) {
          res.writeHead(500);
          return res.end('Error loading test.html');
        }
    
        res.writeHead(200);
        res.end(data);
      });
    }
    
    io.on('connection', (socket) => {
      var handshakeData = socket.request;
    
      const userName = handshakeData._query['user'];
      console.log('userName', userName);
      if (!userName || userName === 'null') {
        console.log('Disconnecting...');
        return socket.disconnect();
      }
    
      const onLeave = () => {
        console.log('disconnecting', userIdMap[socket.id]);
        socket.broadcast.emit(
          'userDisconnect',
          `${userIdMap[socket.id]} is disconnected`
        );
        delete userIdMap[socket.id];
      };
    
      userIdMap[socket.id] = handshakeData._query['user'];
      console.log('userIdMap', userIdMap);
    
      socket.emit('news', { hello: 'world' });
    
      socket.on('disconnect', onLeave);
      socket.on('close', onLeave);
    });
    

    在上面的代码中,

    • 我维护了一个用户名和 socket.id 的映射,它对于每个连接都是唯一的。
    • 用户名存储在地图中 - userIdMap。请注意我是如何从查询中读取用户名的。
    • 我正在使用socket.broadcast.emit() 向所有客户广播,以防有人离开(标签关闭或重新加载)。
    • 我们将在userDisconnect 活动中进行广播,以防有人离开。客户端必须添加一个侦听器才能收到通知。

    下面是客户端实现:

    <script src="https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js"></script>
    <script>
      var user = user;
      if (!user) {
        user = prompt('Please choose a username:');
        if (!user) {
          alert('Your name has been set to "Anonymous"');
        } else {
          alert('Your name has been set to "' + user + '"');
        }
      }
    
      var socket = io('http://localhost:3000', { query: `user=${user}` });
    
      socket.on('connect', (data) => {
        var handshakeData = socket.request;
        console.log('connect', data);
      });
    
      socket.on('news', function (data) {
        console.log('news', data);
      });
    
      socket.on('userDisconnect', (data) => alert(data));
    </script>
    

    希望这会有所帮助:) 快乐编码

    【讨论】:

      猜你喜欢
      • 2015-05-17
      • 1970-01-01
      • 1970-01-01
      • 2013-03-31
      • 2020-05-26
      • 1970-01-01
      • 2021-10-10
      • 1970-01-01
      • 2020-02-13
      相关资源
      最近更新 更多