简体   繁体   English

socket.io:正确更改房间并在同一HTML页面中实现聊天

[英]socket.io: correctly change rooms and implement chat in the same HTML page

Problem : I have to implement chat with an option to change a room using socket.io. 问题 :我必须通过使用socket.io的选项来实现聊天功能。 I tried to do it with a single HTML file on the client-side, but clients from different rooms wrote in the same textarea so rooms do not work . 我尝试使用客户端上的单个HTML文件来执行此操作,但是来自不同会议室的客户端在同一textarea中进行了编写,因此会议室无法正常工作 That´s why I created 2 separate HTML pages just to make my rooms work. 这就是为什么我创建2个单独的HTML页面只是为了让我的房间正常工作的原因。

And it works just fine, but I want to have a more slick solution: make all client-side logic in 1 single HTML file . 它工作得很好,但是我想有一个更漂亮的解决方案: 将所有客户端逻辑都放在一个HTML文件中

Here´s my server-side code, chat.js : 这是我的服务器端代码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);

My main room code, mainRoom.html : 我的主要房间代码mainRoom.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>

My second room code is almost the same, except for the line, where I connect to room´s URL: 我的第二个房间代码几乎相同,除了我连接到房间URL的那一行:

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

The question : how can I combine 2 rooms into 1 HTML file? 问题 :如何将2个房间合并为1个HTML文件?

I would simply make server-side events for joining and leaving rooms. 我只是简单地进行服务器端事件以加入和离开房间。 So you can 所以你可以

  • add an extra step to define the room to join before connecting 在连接之前添加一个额外的步骤来定义要加入的房间
  • or connecting to the default '/' room and then send back a list of possible rooms to join. 或连接到默认的“ /”会议室,然后发回可能加入的会议室列表。

So you would need to make client-side events for emiting "subscribe"(join) & "unsusbscribe"(leave) the rooms and the server does the work. 因此,您将需要进行客户端事件以发出“订阅”(加入)和“取消取消订阅”(离开)房间,然后服务器完成工作。

Here you have an answer that I gave for server-side socket.io joining/leaving rooms 在这里,您有一个我为服务器端socket.io加入/离开房间而给出的答案。

You should also know, a user can be subscribed to multiple rooms, you can avoid that if you wish by unsubscribing the current room when joining a new one. 您还应该知道,一个用户可以预订多个房间,如果愿意,可以在加入新房间时取消订阅当前房间,从而避免这种情况。


EDIT: EXTRA OPTIONS 编辑:额外选项

If you are serving your client from node (express for example) you can also make a param in the GET request (/chat/:room) and that :room param is what is used to connect to that room. 如果从节点(例如,express)为客户端提供服务,则还可以在GET请求(/ chat /:room)中创建一个param ,而:room参数是用于连接到该房间的对象。

I still prefer connecting to the server and then returning to the client a list of possible rooms to join. 我仍然更喜欢连接到服务器,然后将可能加入的房间列表返回给客户端。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM