socket.io的基本概述可以自行阅读:https://www.w3cschool.cn/socket/socket-1olq2egc.html
话不多说,口才不好,直接贴代码吧,页面代码如下(解释全在注释中):
*注:
1、项目结合了typescript,并且接口的入参直接使用的mysql语句(自行理解)进行操作。
2、页面代码可以结合我的node服务器server.js进行对应理解。
3、该聊天室信息建了user_chat(聊天室用户表)和user_record(用户聊天信息表),表结构就不一一列出了。
import React, { useState, useEffect, useCallback } from 'react'; // 使用的是18年发布的Hooks,不懂可自行百度
import io from 'socket.io-client';
import { withRouter } from 'react-router-dom'; // 为了实现this.props.history路由跳转
import {Button, message} from 'antd';
import {getUserId, outLogin} from '../../comment/methods/util'; // 自己获取用户登录ID和退出登录的方法
import {wantShopData} from '../../api/shopApi'; // 自己封装axios请求的方法
import './scoket.scss';
const socket = io();
const user_id = getUserId();
// 判断socket类型
const chatTypeMsg = {
'onlineUserList': '在线用户',
'userLoginChat': '加入聊天室',
'userSendMsg': '用户发送信息'
};
// 用户是否在线
const isOnline = {
'0': '离线',
'1': '在线'
};
let SOCKET_INDEX = 0; // 防抖处理的变量
interface Props {
history: {
push: Function
}
}
function Scoket(props: Props) {
const [userMsg, setUserMsg] = useState({user_nick_name: ''}); // 用户信息
const [chatCode, setChatCode] = useState(''); // 聊天表code
const [chatUserList, setChatUserList] = useState([]); // 所有在线用户
const [userChatMsgList, setUserChatMsgList] = useState([]); // 所有的聊天信息
let isChat = true; // 判断是否第一次进入聊天室
let textareaRef: any = null;
// 异步统一使用async进行同步化
// 获取该用户的个人信息(头像、昵称、用户等级)
let getUserMsg = async () => {
let u_statements = `SELECT user_hpic, user_nick_name, user_level FROM userMsg WHERE user_id = '${user_id}'`;
await wantShopData({statements: u_statements}).then(data => {
if(data.length === 0) { // 简单处理直接操作session的行为
message.warning('非法登录', 1.5, () => {
outLogin();
props.history.push('/');
});
return;
}
let msg = data[0];
setUserMsg(msg); // 更新userMsg
socket.emit('welcome to me', { msg: msg.user_nick_name }); // emit传递数据,表示你已加入到聊天室
if(!isChat) { // 要是为false则该用户不是第一次进入聊天室
return;
}
// 加入到聊天表
msg.user_hpic = msg.user_hpic ? msg.user_hpic : '/static/images/all/user.jpg';
msg.user_level = msg.user_level ? msg.user_level : '普通用户'