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:
socketManager.getIo.emit("event_name", data); // shout
  • Broadcast a message to a specific client:
socketManager.getSocketFromUserID(userID).emit("eventName", data); // whisper
  • Listen for messages on client:
socket.on("event_name", (data) => {
    // do something with data
});
  • The socketManager class is defined for demonstration, in real life, please define by yourself.

Usage

// 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);
    };
  }, []);
}
// 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
http://example.com/2024/07/21/MIT_Weblab/socket/
Author
Songlin Zhao
Posted on
July 21, 2024
Licensed under