反应的socket.io聊天问题

Posted

技术标签:

【中文标题】反应的socket.io聊天问题【英文标题】:socket.io chat problems with react 【发布时间】:2020-06-10 15:43:17 【问题描述】:

我正在开发一个 create-react-app 项目,并试图整合一个由 sockets.io 提供支持的聊天控制台。问题是,当前端正确捕获聊天消息,发送回io服务器,然后发出,前端成功捕获这些消息时,用户之间没有任何信息传递,一切都只是发生在单个浏览器实例上。 在后端,当有人连接时,我有一个控制台记录“新客户端已连接”。我注意到每次发送消息时控制台都会触发几次,这让我认为问题出在反应重新渲染过程中的某个地方(因此重新渲染正在触发重新连接到套接字服务器。)

代码:

服务器:

const express = require("express");
const http = require("http");
const socketIo = require("socket.io");

const PORT = process.env.PORT || 4001;
const index = require("./routes/index");

const app = express();
app.use(index);

const server = http.createServer(app);

const io = socketIo(server);

io.on("connection", socket => 
  console.log("New client connected");
  socket.on("chat message", function(msg) 
    console.log("message: " + msg);
    socket.emit("chat message", [msg]);
  );
  socket.on("disconnect", () => console.log("Client disconnected"));
);

server.listen(PORT, () => console.log(`Listening on port $PORT`));

app.js(根组件)

import React,  useState, useEffect  from "react";
import "./App.css";
import Board from "./components/Board/Board";
import TileCard from "./components/TileCard/TileCard";
import Chat from "./components/Chat/Chat";
import Choice from "./components/Choice/Choice";
import Header from "./components/Header/Header";

import socketIOClient from "socket.io-client";

function App() 
  const socket = socketIOClient("http://127.0.0.1:4001");
  const [textValue, setTextValue] = useState("");
  function handleChatSend(chatMsg) 
    setTextValue(chatMsg);
    socket.emit("chat message", chatMsg);
  

  useEffect(() => 
    socket.on("chat message", msg => 
      setTextValue(msg);

      console.log("receiving:" + msg);
    );
  , [textValue]);

  return (
    <>
      <Header />

      <div className="content-container">
        <Board />

        <div className="cards-container col">
          <Chat handleChatSend=handleChatSend textValue=textValue />
          <TileCard />
          <Choice />
        </div>
      </div>
    </>
  );


export default App;

聊天组件:

import React from 'react';
import "./chat.css"

function Chat (handleChatSend, textValue) 

   return (
      <div className="chatbox">
         <ul id="messages">
         textValue !== "" ? <li>textValue</li> : null
         </ul>
    <form onSubmit=event =>
       event.preventDefault();
       let chatMsg = event.target.elements[0].value;
       handleChatSend(chatMsg)>
      <input type="text" id="m" autoComplete="off" /><button type="submit">Send</button>
    </form>
      </div>
   )


export default Chat; 

【问题讨论】:

在服务器中将 socket.emit("chat message", [msg]); 更改为 io.emit("chat message", [msg]); 成功了!非常感谢,我已经为此奋斗了好几个小时...... @Omer 您的评论值得百万票赞成。太棒了,我现在可以看到套接字的魔力了。过去两天我一直面临同样的问题 【参考方案1】:

正如 Omer 在评论中提到的,我们需要使用 io 而不是使用套接字来发出事件,这就是我犯错的地方。在按照 Omer 的建议进行操作之后,socket 就像奇妙而真实的魔法一样工作

我是如何从后端向客户端发出响应的

export default function section(io: socketio.Server, socket: Socket) 
  socket.on("update-section", async (payload:  [Key: string]: any ) => 
    // const query: any = socket.handshake.query;
    const updated = await updateSection(
      ...payload,
      //   ...decodeToken(query?.token),
    );
    io.emit(`update-section-response`, updated);
  );

  socket.on("delete-section", async (sectionId: string) => 
    const deleted = await deleteSection(sectionId);
    io.emit(`delete-section`, deleted);
  );

【讨论】:

以上是关于反应的socket.io聊天问题的主要内容,如果未能解决你的问题,请参考以下文章

Socket.io Express Http-Server 后端,CORS 错误

使用 socket.io 管理多个聊天室的正确方法是啥?

一次与两个用户随机聊天(Socket.io)

Phonegap Socket.io 聊天

js节点-socket.io聊天修改

使用 Socket.IO 和 NodeJS 实现音频聊天