MIT Weblab笔记 - Sockets

Introduction

Steps for a http request:

  • Client sends request to Server
  • Server responds to client

If we want to achieve a live chat function, where

  • A user sends a message
  • All users can see the updates message immediately without refreshing the page

However, server cannot send a message without a request. Sockets can solve this!

Sockets

Syntax

  • Broadcast a message from server to everyone connected:
1
socketManager.getIo.emit("event_name", data); // shout
  • Broadcast a message to a specific client:
1
socketManager.getSocketFromUserID(userID).emit("eventName", data); // whisper
  • Listen for messages on client:
1
2
3
socket.on("event_name", (data) => {
// do something with data
});
  • The socketManager class is defined for demonstration, in real life, please define by yourself.

Usage

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Frontend:
const Chatbook = (props) => {

const [activeChat, setActiveChat] = useState({
recipient: ALL_CHAT,
messages: [],
});

const addMessages = (data) => {
setActiveChat(prevActiveChat => ({
recipient: prevActiveChat.recipient,
messages: prevActiveChat.messages.concat(data),
}));
};

useEffect(() => {
socket.on("message", addMessages);
return () => {
socket.off("message", addMessages);
};
}, []);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Backend:
router.post("/message", auth.ensureLoggedIn, (req, res) => {
console.log(`Received a chat message from ${req.user.name}: ${req.body.content}`);

// insert this message into the database
const message = new Message({
recipient: req.body.recipient,
sender: {
_id: req.user._id,
name: req.user.name,
},
content: req.body.content,
});
message.save();
socketManager.getIo().emit("message", message);
});

What happens in the code:

  1. When the Chatbook component mounts, it sets up a socket listener for the “message” event using useEffect. socket.on("message", addMessages) adds a listener that calls addMessages whenever a new message is received. When the component unmounts, it calls the return statemnet: socket.off("message", addMessages), which cleans up the event listener.
  2. A user sends a POST request to the /message endpoint with the chat message content and recipient information.
  3. The backend creates a new message and saves it to the database.
  4. socketManager.getIo().emit("message", message): The message is emitted to all connected clients using Socket.io, with data “message”.
  5. socket.on("message", addMessages) listener calls the addMessages function with “message” as parameter, updating the existing messages.
  • setActiveChat here can also accept a function as an argument. This function receives the previous state prevActiveChat as its argument.

MIT Weblab笔记 - Sockets
https://thiefcat.github.io/2024/07/21/MIT-Weblab/socket/
Author
小贼猫
Posted on
July 21, 2024
Licensed under