6

我是 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>
4

2 回答 2

5

看看这里 - 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/

玩得开心。

于 2013-09-06T15:34:12.053 回答
0

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

客户:

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 => 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 => socket.id也很有用。

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

于 2022-01-20T20:23:50.543 回答