koa+React实现在线聊天室

通过一些简单的技巧,实现群聊与私聊效果!

 

聊天室介绍:

        整体的UI构建以及数据处理均个人设计,目前已经嵌入个人博客,后期将不定期的开放博客供大家使用测试。

        基于socket.io实现的实时数据响应,目前实现了群聊和私聊的功能,在此之上添加了用户添加好友、在线用户预览功能......(需要源码请私聊

 socket.io参考文档:https://socket.gitbook.io/docs/2-wen-dang-docs

集成步骤:

后端Koa

Koa添加依赖:

const socket = require("socket.io");

将socket服务挂载在koa主服务上(切记端口不能冲突):

const server=app.listen(3001,()=>{
    console.log('http://localhost:3001')
});

const io = socket(server, {
    cors: {
        origin: "http://localhost:3000",
        credentials: true,
    }
})

在socket内定义私聊和群聊事件:

io.on("connection", (socket) => {
       socket.on('online',data=>{
           socket.join(data.sessionID)
       })
      //群聊发送信息
      socket.on("sendGroupMessage",data=>{
          const date = getDate().createTime
         io.emit('groupReceive',{
             ...data,
             sendTime:date
         })
      })
    //单聊发送信息
    socket.on("sendSomeOneMessage",data=>{
        const date = getDate().createTime
        io.to(data.sessionID).emit('someOneReceive',{
            ...data,
            sendTime:date
        })
    })
});

至此,后端代码就集成完了,集成完之后,记得重启你的Koa项目

前端React

项目的目录结构(由于数据的响应冲突,建议将群聊和私聊分为两个组件)

 React添加依赖,在父类配置socket:

import {io} from "socket.io-client";

export default function ChatRoom(){

    const socket = io(config.socketURL);

} 

将socket向子组件分发(主要就是信息接收显示和信息数据发送):

      <div className='chatRoom-right'>
                   <div className='chatRoom-header'>
                       <CloseCircleTwoTone style={{fontSize:'18px',float:'right'}} onClick={()=>closeChat()}/>
                       <h3> {headerData}</h3>

                   </div>
                   <div className='messageBox'>
                       {messageShow==='block'?<GroupMsgBox socket={socket} userInfo={userInfo}/>:
                           <MessageBox clickData={clickData} socket={socket} userInfo={userInfo} />
                       }
                   </div>
                     <div className='inputBox'>
                         <InputBox socket={socket}
                                   messageShow={messageShow}
                                   userInfo={userInfo}
                                   clickData={clickData}
                                   clickUserInfo={clickUserInfo?clickUserInfo.username:null}
                                   sessionID={sessionID?sessionID:null}
                           />
                     </div>
      </div>

输入框内向后台传递数据(通过messageShow字段判断群聊还是私聊):

   const onFinish=(data)=>{
         const messageData=utf16toEntities(data.message)
        if(clickData===null){
            // message.warning('请勿违规操作');
        }else {
            sendMessage({
                userAvatar:user.userAvatar,
                username:user.username,
                nick:user.nick,//谁发的信息,由于数据加载问题,不得不用简短的字段
                toSomeone:clickData,//传的是唯一ID或all
                message:messageData
            }).then(()=>{
                form.current.resetFields()
                if(messageShow==='block'){
                    socket.emit('sendGroupMessage',{
                        ...user,
                        ...data,
                        sessionID
                    })
                }else {
                    socket.emit('sendSomeOneMessage',{
                        ...user,
                        ...data,
                        sessionID
                    })
                }
            })

        }
    }

信息框分别监听群聊和私聊事件(将获取的数据通过useState存入,实时刷新信息数据):

   //好友之间信息传递
    socket.on('someOneReceive',datas=>{
            setArrivalMessage(datas)
    })
  //群聊信息传递
    socket.on('groupReceive',datas=>{
        setArrivalMessage(datas)
    })

信息数据渲染(支持实时滚动条底置,显示最新的数据):

    //使得滚动条始终保持在最下方
    useEffect(()=>{
        const current = scrollEvent.current
        current.scrollTop=current.scrollHeight
    },[data])
 <div className='messageBox'  ref={scrollEvent}>
            { data.map((item,index)=>{
                return(
                    <div key={index} className={`${item.username===user.username?"mine":"others"}`}>
                        <Avatar src={item.userAvatar} className='avatar'/>
                        <div className='container'>
                            <h5>{item.nick}</h5>
                            <div className='bubble'>
                                {item.message}
                            </div>
                        </div>
                        <div className='time'>
                            {item.sendTime}
                        </div>
                    </div>
                )
            })}
        </div>

代码集成注意事项

群聊和私聊数据最好还是分开响应,在开发的过程中产生了各种数据冲突。最后向大家分享MySQL的字段配置(信息存储、好友信息存储

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hyacinth~z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值