WebSocket的实现(react+socket.io)

后端下载依赖:

yarn  add  socket.io  // 采用socket.io进行实时通信

 在router/index.js中配置连接

var express = require('express');
var router = express.Router();
const http = require('http');
const socketIO = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketIO(server, {
    cors: {
        origin: '*'
    }
});


// 在线用户列表
let userList = []

// 用户连接
io.on('connection', (socket) => {
    console.log('用户连接成功');
    let userSocketId = socket.id;
    // 初始化 数据
    socket.on('userData', (data) => {
        let idx = userList.findIndex(item => {
            return item._id === data._id
        })
        if (idx === -1) {
            userList.push(data)
        }
        io.emit('online', userList)

        // 设置当前用户的userid
        socket.emit('userid', { user: data, userId: userSocketId, })
    });



    // 接收客户端发送的消息
    socket.on('message', ({ partner, user, message }) => {
        socket.to(partner.userID).emit('sendOne', message)
    })

    // 用户离开
    socket.on('disconnect', () => {
        console.log('用户离开');
    });

    // 离开时 获取到的 用户信息
    socket.on('leave', (data) => {
        let idx = userList.findIndex(item => item._id === data._id);
        // 离开时 删除在线人员
        userList.splice(idx, 1)
        // 离开时 更新在线人员
        io.emit('online', userList)
    })
});

server.listen(3000, () => {
    console.log('Server is running on port 3000');
});

前端依赖

yarn  add  socket.io-client   // 前端采用 socket.io-client 来实现实时通信

import React, { useEffect, useState } from 'react'
import '../css/DetailChat.scss'
import { useLocation, useNavigate } from 'react-router-dom'
import { Toast, NavBar, Input, Button } from 'react-vant';
import { WapNav } from '@react-vant/icons';
import io from 'socket.io-client';
import axios from 'axios';


export default function DetailChat() {
    const socket = io('http://localhost:3000'); // 指定服务器的URL
    let location = useLocation()
    const Navigate = useNavigate()
    // 对象数据
    let partner = location.state;
    // 当前用户数据
    let userData = JSON.parse(sessionStorage.getItem('user')) || []
    // 定义输入框的信息
    const [iptValue, setIptValue] = useState('')
    // 保存聊天记录
    const [record, setRecord] = useState([])

    // 发送消息
    const send = async () => {
        let { data } = await axios.get(`http://localhost:3002/getPartner?id=${partner._id}&uid=${userData._id}&message=${iptValue}`)

        if (data.code === 200) {
            socket.emit('message', { partner: data.data[0], user: data.data[1], message: iptValue })
            setIptValue('')
            getrecord()
        }
    }
    // 用户连接
    useEffect(() => {
        getrecord()
        socket.on('connect', () => {
            // 发送用户信息到服务器
            socket.emit('userData', userData);

            // 设置userid
            socket.on('userid', data => {
                saveData(data)
            })
        })

        // 接收数据
        socket.on('sendOne', (data) => {
            getrecord()
        })

        return () => {
            socket.emit('leave', userData) // 离开时传递 用户信息
            socket.disconnect(); // 组件卸载时断开连接
        };
    }, []);

    // 监听新消息保持在最底部--- 获取最后一条消息
    useEffect(() => {
        let lasrChild = document.querySelector('.detailChat-message').lastElementChild
        if (lasrChild) {
            lasrChild.scrollIntoView(false)
        }
    }, [record])

    // 初始化  --- 保存用户的连接 id
    const saveData = async (user) => {
        await axios.post('http://localhost:3002/saveData', user)
    }

    // 获取聊天记录
    const getrecord = async () => {
        let { data } = await axios.get(`http://localhost:3002/getrecord?user1=${partner._id}&user2=${userData._id}`)
        setRecord(data.data)
    }

    // 返回
    const goback = () => {
        Navigate('/chat')
    }
    return (
        
{/* 个人聊天 -- 顶部区域 */}
} onClickLeft={goback} onClickRight={() => Toast('按钮')} />
{/* 聊天记录显示区域 */}
{ record.map((item, index) => { return (
{ item.sendUser === userData._id ?
{item.message}
:
{item.message}
}
) }) }
{/* 个人聊天 -- 底部输入区域 */}
setIptValue(value)} onKeyDown={(e) => e.keyCode === 13 ? send() : ''} prefix="" suffix={} placeholder="请输入发送的内容" />
) }

实现效果展示:

WebSocket的实现

你可能感兴趣的:(websocket,网络协议,网络)