通过一些简单的技巧,实现群聊与私聊效果!
聊天室介绍:
整体的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的字段配置(信息存储、好友信息存储)