聊天室前端页面设计

# 聊天记录 part

  • 展示:用 logs 的 state 来记录需要展示的聊天记录

  • 查询:用户只有三个场景会更新聊天记录

    • 自己发送了信息,这个时候是主动发送type: 'message'消息到后端,后端接受到了之后,会对该聊天室下所有用户返回type === 'message'的消息类型,即是刚才主动发送的消息
const sendMessage = () => {
  if (!inputValue) {
    message.warning('空消息');
    return;
  }
  if (ws.current && ws.current.readyState === WebSocket.OPEN) {
    const info = {
      content: inputValue,
      sendUserName: nickName,
      sendUserId: nickId,
      sendRoom: roomId,
      sendTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
      type: 'message',
    };
    ws.current.send(JSON.stringify(info));
    setInputValue(''); // 清空输入框
  }
};
  • 其他用户发送了信息,这个时候是被动更新,前端只需要处理 websocket 实例返回的消息即可,这里我对消息进行了 type 类型分类,type === 'message' 的时候,即是被动接受了其他用户发来的消息
// 接收到消息
ws.current.onmessage = (event) => {
  handleReciveMessage(event.data);
};

// 处理 接受到的消息
const handleReciveMessage = (dataStr) => {
  const parseData = JSON.parse(dataStr);
  for (let item of parseData) {
    const { type, data } = item;
    if (type === 'logs') {
      setLogs(data);
      scrollToBottom();
    }
    if (type === 'members') {
      setOnlineMembers(data);
    }
    if (type === 'message') {
      setLogs((prev) => [...prev, data]);
      scrollToBottom();
    }
  }
};
  • 用户主动获取聊天室之前的聊天记录,这个场景对应的新加入的用户想看之前的聊天内容,这里我先主动发送 type: 'query-logs'的消息到后端,后端会返回type === 'logs' 的消息类型,即是历史 200 条的聊天记录
// 请求最近的聊天记录
const getLogs = async () => {
  if (ws.current && ws.current.readyState === WebSocket.OPEN) {
    const info = {
      content: '',
      sendUserName: nickName,
      sendUserId: nickId,
      sendRoom: roomId,
      sendTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
      type: 'query-logs',
    };
    ws.current.send(JSON.stringify(info));
  }
};

# 在线成员 part

  • 展示:用 onlineMembers 的 state 来记录需要展示的在线用户

  • 查询:用户只能被动接受这个消息的变更,有用户登入或者用户登出的时候,后端会广播这条消息到前端,类型是type === 'members' 的时候,即是被动接受了用户登入登出的消息

// 代码 在 handleReciveMessage 里面处理了

# 发送消息 part

  • 展示:用 inputValue 的 state 来进行消息管理

  • 发送:用户主动发送消息,回车或者点击发送 icon 进行发送,需要注意的是每次发送完之后记得清空 input

// 代码 在 sendMessage 里面