如何在页面刷新后从socket.io重新连接socket示例?

h7appiyu  于 2021-09-13  发布在  Java
关注(0)|答案(0)|浏览(478)

试图用express+socket.io制作一个简单的聊天应用程序并做出React,但这个问题一直折磨着我的大脑。每当我刷新消息应用程序路由上的页面时,我都无法发送任何消息。我试图通过使用带有历史api的react路由器将我发送回主页来规避这个问题。但是,当我返回主页时,我无法重新进入聊天页面,除非我再次刷新主页。每当我刷新页面时,套接字对象似乎都是空的。
服务器代码:

const room = "general";
const room2 = "memes";

const LOGIN = "loginEvent";
const NEW_MESSAGE_EVENT = "newMessageEvent";
const LEAVE_EVENT = "leaveEvent";

io.on("connection", (socket) => {
  socket.on(LOGIN, ({ nickname, room }, callback) => {
    const user = addUser(socket.id, nickname, room);
    socket.join(user.room);
    callback();
    // socket.emit()
  });

  socket.on(NEW_MESSAGE_EVENT, (data) => {
    console.log(data);
    io.in(room).emit(NEW_MESSAGE_EVENT, data);
  });

  socket.on("disconnect", () => {
    const deletedUser = delUser(socket.id);
    console.log("User deleted:", deletedUser);
    if (deletedUser) {
      io.in(room).emit(LEAVE_EVENT, {
        notification: `User ${deletedUser.nickname} has just left`,
      });
    }
    socket.leave(room);
  });
});

在客户端中,我使用react上下文api存储套接字对象,如下所示:

import React, { createContext } from "react";
import io from "socket.io-client";

const SocketContext = createContext();

const SocketProvider = ({ children }) => {
  const ENDPOINT = "http://localhost:3030";
  const socket = io(ENDPOINT);
  return (
    <SocketContext.Provider value={socket}>
      {children}
    </SocketContext.Provider>
  );
};

export { SocketContext, SocketProvider };

然后,我创建一个钩子来发送消息:

import { useState, useContext, useEffect } from "react";
import { SocketContext } from "../contexts/socketContext";

const NEW_MESSAGE_EVENT = "newMessageEvent";

const useRoom = () => {
  const socket = useContext(SocketContext);
  const [messages, setMessages] = useState([]);

  useEffect(() => {
    socket.on(NEW_MESSAGE_EVENT, (message) => {
      const incomingMessage = {
        ...message,
        isOwner: message.id === socket.id,
      };
      setMessages((messages) => [...messages, incomingMessage]);
    });
    return () => {
      socket.close();
    };
  }, [socket]);

  const sendMessage = (message) => {
    socket.emit(NEW_MESSAGE_EVENT, { body: message, id: socket.id });
  };

  return { messages, sendMessage };
};

export default useRoom;

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题