socket.io+html网页聊天室输入昵称时反复循环,不能正确返回信息

用户离开聊天室没有提示
在输入昵称后输入信息会回到输入昵称的步骤,可能是每次输入信息并点击发送后就会刷新页面:

img

且在启动服务器后未打开网页的情况下一直提示有用户连接:

img

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var usocket = {};

const express = require('express');
app.use(express.static('public'));

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/public/Introduction.html');
});


io.on('connection', function(socket){
  console.log('a user connected')

  socket.on("join", function (name) {
    usocket[name] = socket
    io.emit("join", name)
  })

  socket.on("message", function (msg) {
    io.emit("message", msg) //将新消息广播出去
  })

});

http.listen(8080, function() {
  console.log('listening on *:8080');
});

<!doctype html>
<html>

<head>
  <title>客户群聊界面</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: '微软雅黑'
    }

    #container {
      width: 100%;
      height: 1700px;
      background: #eee;
      position: relative;
      box-shadow: 40px 40px 110px #777;
    }

    .header {
      background: #25421ab0;
      height: 80px;
      color: #fff;
      line-height: 68px;
      font-size: 40px;
      padding: 0 20px;
    }


    body {
      width: 100%;
      background: #eee;
      position: relative;
      font: 60px;
    }

    form {
      background: #000;
      position: fixed;
      bottom: 0;
      width: 100%;
    }

    form input {
      border: 0;
      width: 80%;
      font-size: 40px;
    }

    form button {
      width: 20%;
      background: rgb(130, 224, 255);
      border: none;
      font-size: 40px;
    }

    #messages {
      list-style-type: none;
      margin: 0;
      padding: 0;
      font-size: 40px;
    }

    #messages li {
      padding: 5px 10px;
      font-size: 40px;
    }

    #messages li:nth-child(odd) {
      background: #eee;
    }
  </style>
  <script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head>

<body>
  <div class="header">
    <span style="float: left;">Chat room</span>
    <!--<span style="float: right;">14:21</span>-->
  </div>
  <ul id="messages"></ul>
  <form action="">
    <input id="m" placeholder="说点什么吧..." autocomplete="off" /><button>发送</button>
  </form>
</body>

<script src="/socket.io/socket.io.js"></script>
<script>
  var name = prompt("请输入你的昵称:");
  var socket = io()

  //发送昵称给后端,并更改网页title
  socket.emit("join", name)
  document.title = name + "的群聊"

  socket.on("join", function (user) {
    addLine(user + " 加入了群聊")
  })

  //接收到服务器发来的message事件
  socket.on("message", function (msg) {
    addLine(msg)
  })

  //当发送按钮被点击时
  $('form').submit(function () {
    var msg = $("#m").val() //获取用户输入的信息
    socket.emit("message", msg) //将消息发送给服务器
    $("#m").val("") //置空消息框
    return false //阻止form提交
  })

  function addLine(msg) {
    $('#messages').append($('<li>').text(msg));
  }
</script>

</html>

测试了题注代码视乎没问题,node代码部分改成了下面这样,用题注测试的链接服务器时会404.

img

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/230231
  • 这篇博客你也可以参考下:socket.io实时监控数据库,数据变化更新页面
  • 除此之外, 这篇博客: socket.io前后端实践及转发、多服务问题中的 最终方案 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 新创建一个新的域名用于socket.io的转发,这样子只需要配置/路径转发就行,同时设置websocket升级请求头

    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    
  • 以下回答由chatgpt基于相关博客总结生成:

    对于socket.io和html网页聊天室中输入昵称时反复循环且无法正确返回信息的问题,可以采取以下措施进行优化:

    1.前端代码中使用debounce或throttle函数来限制输入昵称时频繁触发emit事件的问题;

    2.前端代码中增加校验逻辑,防止用户输入空白昵称或重复昵称等问题;

    3.后端代码中增加判断逻辑,防止给自己发送消息或向不存在房间发送消息等问题;

    4.对于用户离开聊天室的情况下,可以在前端代码中触发emit事件通知后端,后端再通过广播事件向其他用户发送提示信息,提示该用户已离开;

    5.对于服务器启动但是网页未打开的情况下停止提示有用户连接的信息,可以在后端代码中增加判断逻辑,判断socket连接的数量是否为0,如果为0则不做处理。

    以下是一组基于以上措施的示例代码:

    前端代码:

    let inputTimer = null;
    const inputElem = document.querySelector('#nickname-input');
    
    // debounce函数
    function debounce(func, wait) {
      return function() {
        clearTimeout(inputTimer);
        inputTimer = setTimeout(() => {
          func.apply(this, arguments);
        }, wait);
      };
    }
    
    inputElem.addEventListener('input', debounce(() => {
      const nickname = inputElem.value.trim();
      if (nickname) {
        socket.emit('setNickname', nickname);
      }
    }, 500));
    
    socket.on('nicknameSet', (nickname) => {
      // 显示昵称设置成功提示
    });
    
    socket.on('nicknameRepeat', () => {
      // 显示昵称重复提示
    });
    
    socket.on('messageReceived', (from, message) => {
      // 显示聊天信息
    });
    
    window.addEventListener('beforeunload', () => {
      socket.emit('leaveRoom');
    });
    
    socket.on('userLeft', (nickname) => {
      // 显示用户已离开提示
    });
    

    后端代码:

    const express = require('express');
    const app = express();
    const http = require('http');
    const server = http.createServer(app);
    const { Server } = require('socket.io');
    const io = new Server(server);
    let nicknameSet = false;
    
    // 监听连接
    io.on('connection', (socket) => {
      if (nicknameSet) { // 防止重复设置昵称
        socket.emit('nicknameRepeat');
        return;
      }
    
      // 监听设置昵称
      socket.on('setNickname', (nickname) => {
        if (!nickname) { // 检查空白昵称
          return;
        }
        nicknameSet = true;
        socket.nickname = nickname;
        socket.emit('nicknameSet', nickname);
        socket.broadcast.emit('userJoined', nickname);
      });
    
      // 监听发送聊天信息
      socket.on('sendMessage', (message) => {
        if (nicknameSet && message) {
          io.emit('messageReceived', socket.nickname, message);
        }
      });
    
      // 监听离开聊天室
      socket.on('leaveRoom', () => {
        if (nicknameSet) {
          io.emit('userLeft', socket.nickname);
        }
      });
    });
    
    server.listen(3000, () => {
      console.log('listening on *:3000');
    });
    
  1. 在输入昵称时出现循环,可能是因为您的代码在处理消息时发生了死锁。请确保您的代码能够正确处理每个消息并正常返回结果。
  2. 网页无法正确收到返回信息,可能是因为消息未按预期格式返回。请确保您的代码在发送和接收消息时使用相同的格式,并且各个字段按正确顺序。
  3. 您使用的 socket.io 版本可能过旧或过新,与您的代码不兼容。请确认您使用的版本与文档一致,并尝试升级或降级版本以适配您的代码。

为了更好地帮助您解决问题,您可以提供以下信息:

  1. 相关代码段,尤其是与聊天室、昵称输入和消息处理相关的部分。
  2. 报错信息或日志文件,以便我们更好地定位问题。
  3. 您的运行环境,例如操作系统、Node.js 版本等。
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632