编写一个基于React的聊天室

前言

此前已经编写了一版后端的im,此次就用其作为服务端,可查看参考资料1

代码

使用WebStorm创建React项目

安装依赖包

复制代码
PS C:\learn-demo\front\chatroom> npm install

added 183 packages, and audited 184 packages in 16s

43 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

创建ChatRoom.tsx

复制代码
import React, { useState, ChangeEvent } from 'react';

const ChatRoom: React.FC = () => {
    const [message, setMessage] = useState('');
    const [messages, setMessages] = useState<string[]>([]);
    const [socket, setSocket] = useState<WebSocket | null>(null);
    const [userName, setUserName] = useState('');

    const handleSendMessage = () => {
        if (socket && message) {
            socket.send(message);
            setMessage('');
        }
    };

    const handleConnected = () => {
        if (userName) {
            setUserName(userName);
            createWebSocket(userName);
        }
    };

    const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
        setMessage(event.target.value);
    };

    const handleInputName = (event: ChangeEvent<HTMLInputElement>) => {
        setUserName(event.target.value);
    };

    const createWebSocket = (userName: string) => {
        setMessages(prevMessages => [...prevMessages, `welcome 【${userName}】`])
        if (userName){
            setUserName(userName);
        }else {
            return;
        }
        //关闭已有websocket连接
        if (socket){
            socket.close()
        }
        const newSocket = new WebSocket(`ws://localhost:18080/ws?userName=${userName}`);
        newSocket.onopen = () => {
            console.log('Connected to the WebSocket server');
        };
        newSocket.onmessage = (event: MessageEvent) => {
            setMessages(prevMessages => [...prevMessages, event.data]);
        };

        newSocket.onclose = () => {
            console.log('Disconnected from the WebSocket server');
        };

        setSocket(newSocket);
    }

    return (
        <div>
            <ul>
                {messages.map((msg, index) => (
                    <li key={index}>{msg}</li>
                ))}
            </ul>
            <input
                type="text"
                value={userName}
                onChange={handleInputName}
            />
            <button onClick={handleConnected}>Connected</button>
            <br/>
            <input
                type="text"
                value={message}
                onChange={handleInputChange}
            />
            <button onClick={handleSendMessage}>Send</button>
        </div>
    );
};

export default ChatRoom;

修改main.tsx

复制代码
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import ChatRoom from "./component/ChatRoom.tsx";

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <ChatRoom />
  </StrictMode>,
)

测试

分别以不同用户名(test1、test2、test3)连接websocket,步骤是第一行输入框输入用户名,然后点击Connected按钮

  • test1发送全体消息

第二行输入框输入消息,点击Send按钮

test2、test3均收到消息

  • test1发送消息给test2

test2收到消息

test3未收到消息

调整后端代码

上述消息分不清到底是谁发给用户的,调整下im服务的代码

SendExecutorFactory

java 复制代码
public void onMessage(String sendUserName, String message) {
    IBaseSendExecutor iBaseSendExecutor = Optional.ofNullable(executorConfiguration.getBaseSendExecutorMap()
            .get(webSocketProperties.getCommunicationType())).orElse(new DefaultSendExecutor());
    message = String.format("【%s】: %s", sendUserName, message);
    //包含@发给指定人,否则发给全部人
    if (StringUtils.contains(message, webSocketProperties.getReceiverSeparator())) {
        iBaseSendExecutor.sendToUser(sendUserName, message);
    } else {
        iBaseSendExecutor.sendToAll(sendUserName, message);
    }
}

重新启动服务端,发送消息

页面上重新连接,test1发送全体消息

test2、test3均收到test1的消息

参考资料

1.im后端代码

2.chatroom前端项目

相关推荐
泯泷3 小时前
手搓JSVMM第 8 篇:函数调用:参数、返回值与调用帧
前端·javascript·前端框架
Sherotree3 小时前
Google Antigravity——Agent 被提到主界面
前端·ide·后端·edge浏览器
里欧跑得慢4 小时前
Flutter 像素级还原:设计稿到代码的视觉无损转换技巧
前端·css·flutter·web
里欧跑得慢4 小时前
Flutter 三方库 function_tree — 鸿蒙应用开发中的动态数学公式解析与计算神器,实现鸿蒙深度适配下的复杂函数逻辑运行时求值实战(适配鸿蒙 HarmonyOS Next ohos)
android·前端·安全·flutter·华为·harmonyos
苏灿烤鱼5 小时前
没有机密文件,也没有付费数据,在浏览器里造一颗"间谍卫星"
前端·javascript·github
泯泷5 小时前
手搓JSVM第 5 篇:写第一个编译器:从 AST 生成 IR
前端·javascript·算法
泯泷5 小时前
手搓JSVM第 7 篇:控制流:if、while 与 jump
前端·javascript·算法
泯泷5 小时前
手搓JSVM第 6 篇:把 IR 编成字节码:emit 与 label fixup
前端·javascript·算法
泯泷5 小时前
手搓JSVM第 3 篇:从栈式 VM 到寄存器式 VM:为什么我们选择寄存器
前端·javascript·算法
泯泷5 小时前
第 4 篇:让 VM 支持变量:Slot、Environment 与 TDZ
前端·javascript·算法