由于时间关系和文字限制,本人直接将代码和简单描述写在这篇文章里面项目前端基于react+socket **

//前端需要依赖包
npm i  socket.io     socket.io-client -D 

后端技术node+express+ socket.io

npm i  socket.io  -S   //后端依赖

前端代码socket聊天室

import React, { Component } from 'react';
import './index.scss';  
import Head from "~/components/head";
//建立与socket服务器的连接  //io.connect http://localhost:4321 
const socket = require('socket.io-client')('http://localhost:4321')
class Chat extends Component {
  constructor(props){
    super(props)
    this.state = {
      friendList:[],
      chatList:[],
      userName:'',
      addInfo:[],
      myclose:false,
      fclose:false
    }
  }
  componentDidMount(){
    let name = window.prompt('请输入昵称');
    if(!name){
      name = Date.now()
    }
    this.setState({userName:name})
    //连接之后,给服务器发送昵称
    socket.emit('message',{type:'online',name,time:new Date().toLocaleString()})

    //接收服务器返回的好友列表
    socket.on('broadcast',(msg)=>{
      this.setState({friendList:msg.friends})
      // console.log(this.state.friendList)
    })
    //新人上线
    socket.on('ON_LINE',(msg)=>{
      // console.log(msg)
      let newInfo = this.state.addInfo;
      newInfo.push(msg)
        this.setState({addInfo:newInfo})
    })
    //好友离开的消息提示
    socket.on('CLOSE',(msg)=>{
      // console.log(msg)
      let newInfo = this.state.addInfo;
      newInfo.push(msg)
        this.setState({addInfo:newInfo})
    })
    //接收别人的消息
    socket.on('CONTENT',(msg)=>{
      let list = this.state.chatList;
      list.push({user:msg.user,txt:msg.txt})
      this.setState({chatList:list})
    })
    //监听服务器的连接
    socket.on('disconnect',()=>{
      this.setState({fclose:true})
    })
  }
  //发送消息
  send(){
    if(this.state.myclose){  //如果用户退出,将发不出消息
      return false
    }else{
      let value = this.refs['textbox'].value;
      this.refs['textbox'].value ='';
      socket.emit('message',{type:'content',content:value})
      let list = this.state.chatList;
      list.push({user:this.state.userName,txt:value})
      this.setState({chatList:list})
    }
  
  }
  //关闭聊天窗口
  closeWindow(){
    if(window.confirm("确认要退出吗?")){
        socket.disconnect();
        this.setState({myclose:true})
    }
  }
  render() {
    let {chatList,userName,addInfo,myclose,friendList,fclose} = this.state
    return (
      <div className="App">
          <Head title="聊天室" show={true}></Head>
        <div className='container'>
            <div className='head'>亲,你来了,有什么可以帮助你的</div>
            <div id="friends-box">
              <p>群成员 <span>{friendList.length}</span></p>
              <ul id="friend-list">
                {
                  friendList.map((name,index)=>{
                        return <li key={index}><em></em><span className={name===userName?"my":''}>{name}</span></li>
                  })
                }
              </ul>
            </div>
            <div id="record-box" ref='record'>
              {
                addInfo.map((v,index)=>{
                  return <div className='addInfo' key={index}>{v.time}   {v.txt}</div>
                })
              }
              {
                chatList.map((v,index)=>{
                  if(v.user==userName){
                      return <div className='right-div move-mine2' key={index} ref='chatitem'>
                                <em className='photo right-photo'></em><span className='name right-name'>{v.user}</span><span className='say right-say'>{v.txt}</span>
                           </div>
                  }else{
                      return <div className='left-div' key={index} ref='chatitem'>
                                <em className='photo left-photo'></em><span className='name left-name'>{v.user}</span><span className='say left-say'>{v.txt}</span>
                           </div>
                  }
                })
              }
              {myclose?<div className='addInfo'>你已退出群聊,收不到好友的消息啦</div>:""}
              {fclose?<div className='addInfo'>服务器断开啦</div>:""}
            </div>
            <div id="send-box">
             <textarea rows="8" cols="80" ref='textbox'></textarea>
                <div className="btn">
                  <button type="button" name="close" onClick={this.closeWindow.bind(this)}>关闭</button>
                  <button type="button" name="send" onClick={this.send.bind(this)}>发送</button>
                </div>
              </div>
            
          </div>
      </div>
    );
  }
}
export default Chat;

后端socket服务


//后端的聊天  开始
//引入socket
const io = require("socket.io")(httpServer);
//httpServer是我本人项目中使用了https服务单独创建的
let clients = [];
let friends = [];
io.sockets.on('connection',(client)=>{
    console.log('有客户端连接')
    clients.push(client)
    //接收用户的信息
    client.on('message',(params)=>{
        switch(params.type){
            case 'online':{
                client.name = params.name;
                client.broadcast.emit('ON_LINE',{time:params.time,txt:'用户'+client.name+'加入聊天'})
                //发送在线的所有客户端
                friends.push(params.name)
                io.sockets.emit('broadcast',{friends})
                // console.log(params)
            };break;
            case 'content':{
                client.broadcast.emit('CONTENT',{user:client.name,txt:params.content})
            };break;
        }
    })
    client.on('disconnect',()=>{
        console.log("客户端退出",client.name)
        let index = friends.findIndex(v=>v===client.name)
        friends.splice(index,1)
        io.sockets.emit('broadcast',{friends})
        client.broadcast.emit('CLOSE',{time:new Date().toLocaleString(),txt:"用户"+client.name+"离开了群聊"})
    })

})

//后端的聊天结束

ok了.


Banshee
124 声望4 粉丝

To die is to die, to live is to suffer