javascript - socket.io:在同一个HTML页面中正确地更换房间并实现聊天

标签 javascript html node.js sockets socket.io

问题:我必须使用 socket.io 实现带有更改房间选项的聊天。我尝试在客户端使用单个 HTML 文件来完成此操作,但来自不同房间的客户端在同一文本区域中写入,因此房间不起作用。这就是为什么我创建了 2 个单独的 HTML 页面只是为了让我的房间正常工作。

它工作得很好,但我想要一个更灵活的解决方案:将所有客户端逻辑放在一个 HTML 文件中

这是我的服务器端代码,chat.js:

"use strict";
let app = require('express')();
let server = require('http').Server(app);
let io = require('socket.io')(server);

app.get('/', (req, res) => {
  res.sendFile(__dirname + "/logs/chat2.html");
});

app.get("/room", (req, res) => {
  res.sendFile(__dirname + "/logs/chat.html");
});

io.on("connect", (socket) => {
  // Notify about a new user
  socket.emit("userSelfNotification", {text: "--SELF-- You successfully entered the server"});
  socket.broadcast.emit("newUserNotification", {text: "--BROADCAST-- New user joined the server"});
  // Send message
  socket.on("message", (message) => {
    io.sockets.emit("newMessage", {text: message});
  });
  socket.on("changeRoom", (socket, message) => {
    socket.join(message.roomUri);
    socket.leave("/");
  });
});

// Create a new room
const room = io.of("/room");

room.on("connect", (socket) => {
  socket.emit("userSelfChangeNotification", {text: "--SELF-- You successfully changed the room"});
  socket.broadcast.emit("newUserNotification", {text: "--BROADCAST-- New user joined the room"});
  socket.on("message", (message) => {
    room.emit("newMessage", {text: message});
  });
});

server.listen(3000);

我的主房间代码,ma​​inRoom.html:

<!DOCTYPE html>
<html lang="eng">
<head>
    <meta charset="UTF-8">
    <title>Chat</title>
<script src="https://code.jquery.com/jquery-3.1.0.min.js" charset="utf-8"></script>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
  let socket = io.connect('http://localhost:3000');
  socket.on("userSelfNotification", (message)=> {
    $("textarea").val($("textarea").val() + message.text + "\n");
  });
  socket.on("newUserNotification", (message) => {
    $("textarea").val($("textarea").val() + message.text + "\n");
  });
  socket.on("newMessage", (message) => {
    $("textarea").val($("textarea").val() + message.text + "\n");
  });
</script>
</head>
<body>
<textarea name="name" rows="8" cols="40"></textarea>
<p></p>
<input type="text" name="text" size="20">
<button type="button" name="button">Send</button>
<button type="button" onclick="location.href='http://localhost:3000/room';" name="changeRoomButton">Change room</button>

<script>
  $(document).on('click', 'button', () => {
    let message = $('input').val();
    socket.emit("message", message);
    $('input').val(null);
  });
  $(document).on("click", "changeRoomButton", () => {
    socket.emit("changeRoom", {roomUri: "/room"});
  });
</script>
</body>
</html>

我的第二个房间代码几乎相同,除了我连接到房间 URL 的行:

let socket = io('http://localhost:3000/room');

问题:如何将 2 个房间合并到 1 个 HTML 文件中?

最佳答案

我只会创建用于加入和离开房间的服务器端事件。 所以你可以

  • 添加额外步骤以在连接之前定义要加入的房间
  • 或连接到默认的“/”房间,然后发回列表 可能加入的房间。

因此,您需要创建客户端事件来发出“订阅”(加入)和“取消订阅”(离开)房间,然后服务器完成这项工作。

这里有我为 server-side socket.io joining/leaving rooms 给出的答案

您还应该知道,一个用户可以订阅多个房间,如果您愿意,可以通过在加入新房间时取消订阅当前房间来避免这种情况。

<小时/>

编辑:额外选项

如果您从 Node (例如express)为客户端提供服务,您还可以在GET请求(/chat/:room)中创建一个param,并且:room param 是用于连接到该房间的参数。

我仍然更喜欢连接到服务器,然后向客户端返回可能加入的房间列表。

关于javascript - socket.io:在同一个HTML页面中正确地更换房间并实现聊天,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45793799/

相关文章:

javascript - Ajax 选择输入点击 : Fill options from Ajax response

javascript - Ember JS : Resolve promise in the success of processing request

javascript - 附加div内容jquery

c# - 在重定向时显示动画 gif 文件直到 asp 页面加载?

javascript - useEffect 不监听 localStorage

node.js - Nodejs 异步模块有事务

node.js - 我可以在 req.get 中发送 http 请求吗?

javascript - React 是否需要将 onClick 作为 props 传递给子组件?

javascript - 仅对父 div 元素调用一次 javascript 事件

html - 传递参数并使用自定义属性?