socket.io实现即时通讯聊天室教程

1,309 阅读4分钟
1.配置服务器域名
socket合法域名配置 'wss://www.服务器地址.com'
2.服务端设计聊天信息数据结构(本文后台以node为例)
// 定义chats集合的文档结构
const chatSchema = mongoose.Schema({
from: {type: String, required: true}, // 发送用户的id
to: {type: String, required: true}, // 接收用户的id
chat_id: {type: String, required: true}, // from和to组成的字符串
content: {type: String, required: true}, // 内容
read: {type:Boolean, default: false}, // 标识是否已读
create_time: {type: Number} // 创建时间
})
// 定义能操作chats集合数据的Model
const ChatModel = mongoose.model('chat', chatSchema) // 集合为: chats
// 向外暴露Model
exports.ChatModel = ChatModel
3.客户端封装暴露函数
// socket 连接插件
const io = require('../../utils/weapp.socket.io.js')
//使用时请将变量sendMessage修改为与服务器约定的格式
//连接函数
export const initIO = (id,receiveMsg) => {
//创建socket对象之前:判断对象是否已经存在,只有不存在才去创建
if(!io.socket){
//连接服务器,得到与服务器的连接对象
let socketUrl = 'wss://www.服务器地址.com'
io.socket = io(socketUrl)
//创建socket对象之后:保存对象
//回调函数
//绑定监听,接收服务器发送的消息
io.socket.on('receiveMsg',(chatMsg)=>{
//只有当chatMsg是与当前用户相关的消息,才保存
if(userid===chatMsg.from || userid===chatMsg.to){
receiveMsg(chatMsg)
//往消息列表里添加数据并渲染 receiveMsg = () => ([...chatMsgs,chatMsg])
}
})
io.socket.on('connect',(data)=>{
console.log('SOCKET连接成功'+data)
}
io.socket.on('connect_error',(data)=>{
console.log('SOCKET连接失败'+data)
}
io.socket.on('connect_timeout',(data)=>{
console.log('SOCKET连接超时'+data)
}
io.socket.on('disconnect',(data)=>{
console.log('SOCKET连接断开'+data)
}
io.socket.on('reconnect',(data)=>{
console.log('SOCKET正在重连'+data)
}
io.socket.on('reconnect_failed',(data)=>{
console.log('SOCKET重连失败'+data)
}
io.socket.on('reconnect_attempt',(data)=>{
console.log('SOCKET正在重连'+data)
}
io.socket.on('error',(data)=>{
console.log('SOCKET连接错误'+data)
}
}
}
//断开函数
export const socketStop = () => {
if(io.socket) {
io.socket.close()
io.socket = null
}
}
3.客户端引入连接socket.io函数
//通过后端接口请求与通讯人相关的聊天信息chatMsgs
import {initIO,socketStop} from '../socket'
//socket 连接插件
const io = require('../../utils/weapp.socket.io.js')
//首次进入聊天室
initIO(id,receiveMsg)
//客户端向服务端主动发消息
io.socket.emit('sendMsg',{from,to,content})//from:发送人,to:接收人,content:发送内容
//断开socket
socketStop()
4.如果服务端有设计心跳功能,需配合后端,如果检测不到心跳,则关闭socket
4.服务端导出建立socket.io模块
const {ChatModel} = require('../db/models')
module.exports = function(server){
const io = require('socket.io')(server)
//监视客户端与服务器的连接
io.on('connection',(socket)=>{
console.log('有一个客户端连接上了服务器')
//绑定监听,接收客户端发送的消息
socket.on('sendMsg',({from,to,content})=>{
console.log('服务器接收到客户端发送的消息',{from,to,content})
//处理数据(保存消息)
//准备chatMsg对象的相关数据
const chat_id = [from,to].sort().join('_')
const create_time = Date.now()
new ChatModel({from,to,content,chat_id,create_time}).save((err,chatMsg)=>{
//向所有连接上的客户端发消息
io.emit('receiveMsg',chatMsg)
})
})
})
}
5.服务端引入socket.io模块
var server = http.createServer(app);
require('../socketIO/socketIO_server')(server)
6.服务端设计获取当前用户与指定id相关用户所有相关聊天信息列表数据接口
请求URL:/chatList
请求方式:GET
参数类型:id(指定人的id),myId(自己id)
返回示例:
{
"code": 0,
"chatMsgs": [
{
"read": false, // 消息是否已读
"from": "5ae1f088d37a442b749fc143",// 发送用户的id
"to": "5ae1ddd99ca58023d82351ae", // 接收用户的id
"chat_id":"5ae1f088d37a442b749fc143_5ae1ddd99ca58023d82351ae",// from和to组成的字符串
"content": "aa", // 内容
"create_time": 1524757443374,// 创建时间
},
{
"read": false, // 消息是否已读
"from": "5ae1f088d37a442b749fc143",// 发送用户的id
"to": "5ae1ddd99ca58023d82351ae", // 接收用户的id
"chat_id":"5ae1f088d37a442b749fc143_5ae1ddd99ca58023d82351ae",// from和to组成的字符串
"content": "aa", // 内容
"create_time": 1524757443374,// 创建时间
}
]
}
//socket服务端向客户端发送的数据
chatMsg:{
"read": false, // 消息是否已读
"from": "5ae1f088d37a442b749fc143",// 发送用户的id
"to": "5ae1ddd99ca58023d82351ae", // 接收用户的id
"chat_id":"5ae1f088d37a442b749fc143_5ae1ddd99ca58023d82351ae",// from和to组成的字符串
"content": "aa", // 内容
"create_time": 1524757443374,// 创建时间
}
//修改指定消息为已读(每次退出聊天室前调此接口)
请求URL:/readmsg
请求方式:post
参数类型:from(发送人的id),myId(自己id)
返回示例:
{code: 0, data: '修改成功'},
//消息列表接口
请求URL:/msgList,
请求方式:get,
参数类型:pageNum(第几页),pageSize(每页数量),from(发送人的id)
返回示例:
{code: 0, data:{
count:20,
msgList:[
{
"from": "5ae1f088d37a442b749fc143",// 发送用户的id
"to": "5ae1ddd99ca58023d82351ae", // 接收用户的id
"chat_id":"5ae1f088d37a442b749fc143_5ae1ddd99ca58023d82351ae",// from和to组成的字符串
"lastContent":'你好啊',//最后一条聊天信息
"header":'...',//头像
"nickname":'',//昵称
"unReadNum":10//未读消息
}
]
}},