【问题标题】:Node.js & Socket.io Adding UsernameNode.js & Socket.io 添加用户名
【发布时间】:2013-09-10 01:51:43
【问题描述】:

我是 socket.io 的新手,我想知道如何使用 socket.io 在这个简单的聊天中添加用户名。提前谢谢各位。我想学习套接字编程。

下面的代码是我的 server.js

//chat service
io.sockets.on('connection', function (socket) {
    socket.on('sendMessage', function (data) {
    socket.broadcast.emit('message', data);
    socket.emit('message', { text: data.text });   
    });   
});

这是我的聊天客户端 index.html

<!-- index.html -->
<html> 
  <body>
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <script>
      $(document).ready(function () {
        var socket = io.connect('http://localhost');
        socket.on('message', function (data) {

          $('#chat').append( '<b>' + data.text + '</b>' + '<br />');

        });
            $('#send').click(function () {
            socket.emit('sendMessage', { text: $('#text').val() });
            $('#text').val('');
        });

            $('#text').keypress(function(event) {
              if(event.keyCode == 13) {
                $('#send').click();
                $('#text').val('');
              }
            });

      });
    </script>

    <div id="chat" style="width: 500px; height: 300px; border: 1px solid black">

    </div>    

    <input type="text" name="text" id="text">
    <input type="button" name="send" id="send" value="send">
  </body>
</html>

【问题讨论】:

    标签: javascript node.js sockets socket.io


    【解决方案1】:

    看看这里 - http://www.tamas.io/2013/05/19/simple-chat-application-using-node-js-and-socket-io/

    最简单的方法是添加人物对象 - 请参阅源代码(文章中的链接)。

    如果您也想实现房间,请阅读:http://www.tamas.io/2013/05/19/simple-chat-application-using-node-js-and-socket-io/

    玩得开心。

    【讨论】:

    【解决方案2】:

    要最简单地为消息添加用户名,请将用户名添加到从客户端到服务器的消息中:

    客户:

    socket.emit("chat message", {username, message});
    socket.on("chat message", ({username, message}) => {
      console.log(username, message);
    });
    

    服务器:

    io.on("connection", socket => {
      socket.on("chat message", data => {
        // send to all clients but the sender
        socket.broadcast.emit("chat message", data);
      });
    });
    

    如果您想“注册”一次用户名,您可以在服务器代码中的每个 io.on("connection" ... 闭包中保留一个变量,然后使用 "register username" 消息让客户端传达他们的用户名(或为他们分配一个在服务器上,或者可选地通过一系列消息协商一个有效的用户名):

    server.js:

    const express = require("express"); // "^4.17.2"
    const app = express();
    const server = require("http").createServer(app);
    const io = require("socket.io")(server); // "^4.4.1"
    
    app.use(express.static("public"));
    
    io.on("connection", socket => {
      let username = "anonymous";
    
      socket.on("chat message", message => {
        io.emit("chat message", {username, message});
      });
      
      socket.on("register username", newUsername => {
        username = newUsername;
      });
    });
    
    server.listen(3000, () => console.log("server listening on port 3000"));
    

    public/index.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.4.1/socket.io.js"></script>
    </head>
    <body>
      <ul id="messages"></ul>
      <form id="message-form">
        <input autocomplete="off" />
        <input type="submit" value="send">
      </form>
    <script>
    const randomStr = (n=10) => [...Array(n)]
      .map(e => String.fromCharCode(~~(Math.random() * 26) + 97))
      .join("")
    ;
    const username = prompt("what's your nickname?") || randomStr();
    const socket = io.connect();
    const messagesContainer = document.querySelector("#messages");
    
    socket.on("connect", () => {
      socket.emit("register username", username);
    });
    
    socket.on("chat message", ({username, message}) => {
      const li = document.createElement("li");
      li.textContent = `[${username}] ${message}`;
      messagesContainer.appendChild(li);
    });
    
    document.querySelector("#message-form")
      .addEventListener("submit", e => {
        e.preventDefault();
       
        if (e.target.elements[0].value) {
          socket.emit("chat message", e.target.elements[0].value);
          e.target.reset();
        }
      })
    ;
    </script>
    </body>
    </html>
    

    对于需要从每个套接字闭包访问所有活动用户的应用,您可以将用户名添加到共享范围内的对象中。

    以下是使用具有映射socket.id =&gt; username 的对象的最小概念证明:

    public/index.html:

    (与上面基本相同,但有以下补充)

    <!-- ... -->
    <h3>current users:</h3>
    <ul id="users"></ul>
    <!-- ... -->
    
    <script>
    // ...
    const usersEl = document.querySelector("#users");
    socket.on("users", ({users}) => {
      usersEl.innerHTML = "";
    
      for (const user of users) {
        const li = document.createElement("li");
        li.textContent = user;
        usersEl.appendChild(li);
      }
    });
    // ...
    </script>
    <!-- ... -->
    

    server.js:

    // ...
    const usersBySocketId = {};
    
    io.on("connection", socket => {
      socket.on("disconnect", () => {
        delete usersBySocketId[socket.id];
        io.emit("users", {users: Object.values(usersBySocketId)});
      });
    
      socket.on("chat message", message => {
        io.emit("chat message", {username: usersBySocketId[socket.id], message});
      });
    
      socket.on("register username", username => {
        usersBySocketId[socket.id] = username;
        io.emit("users", {users: Object.values(usersBySocketId)});
      });
    });
    // ...
    

    在更复杂的应用程序中,您通常会在对象上存储额外的数据。有时usernamme =&gt; socket.id 的反向映射也很有用。

    我尚未验证用户名的唯一性或其他属性,但这是另一个增加复杂性的典型要求。

    【讨论】:

      猜你喜欢
      • 2015-05-29
      • 2021-04-07
      • 1970-01-01
      • 1970-01-01
      • 2014-02-23
      • 1970-01-01
      • 2014-07-29
      • 1970-01-01
      • 2016-05-31
      相关资源
      最近更新 更多