| 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//未读消息 | |
| } | |
| ] | |
| }}, |