消息发送-5:消息处理按照MsgType拆分代码块

This commit is contained in:
bob
2024-09-15 18:16:19 +08:00
parent fda668cae2
commit 5481c73f09
4 changed files with 104 additions and 72 deletions

View File

@@ -0,0 +1,74 @@
import { Msg, Header, MsgType, Body } from '@/proto/msg'
import { proto } from '@/const/msgConst'
import { userStore } from '@/stores'
import { v4 as uuidv4 } from 'uuid'
export const chatConstructor = (toId, content) => {
const header = Header.create({
magic: proto.magic,
version: proto.version,
msgType: MsgType.CHAT,
isExtension: false
})
const userData = userStore()
const body = Body.create({
fromId: userData.user.account,
fromClient: userData.clientId,
toId: toId,
content: content,
tempMsgId: uuidv4()
})
const chatMsg = Msg.create({ header: header, body: body })
const payload = Msg.encode(chatMsg).finish()
const data = encodePayload(payload)
return data
}
export const heartBeatConstructor = () => {
const header = Header.create({
magic: proto.magic,
version: proto.version,
msgType: MsgType.HEART_BEAT,
isExtension: false
})
const heartBeat = Msg.create({ header: header })
const payload = Msg.encode(heartBeat).finish()
const data = encodePayload(payload)
return data
}
export const helloConstructor = () => {
const header = Header.create({
magic: proto.magic,
version: proto.version,
msgType: MsgType.HELLO,
isExtension: false
})
const hello = Msg.create({ header: header })
const payload = Msg.encode(hello).finish()
const data = encodePayload(payload)
return data
}
/**
* 发送前对长度编码,配合服务端解决半包黏包问题
* @param {*} payload
* @returns
*/
const encodePayload = (payload) => {
let num = payload.length
let lenEncode = []
while (num > 0) {
let byte = num & 0x7f
num >>= 7
if (num > 0) {
byte |= 0x80
}
lenEncode.push(byte)
}
return Uint8Array.of(...lenEncode, ...payload)
}

View File

@@ -1,8 +1,8 @@
import { Msg, Header, MsgType, Body } from '@/proto/msg'
import { proto } from '@/const/msgConst'
import { Msg, MsgType } from '@/proto/msg'
import { userStore, messageStore } from '@/stores'
import { v4 as uuidv4 } from 'uuid'
import { generateSign, combineId } from '@/utils/common'
import { chatConstructor, heartBeatConstructor, helloConstructor } from './constructor'
class WsConnect {
/**
@@ -74,12 +74,21 @@ class WsConnect {
}
/**
* 绑定的业务事件
* 绑定事件
*/
events = {
delivered: () => {}
}
/**
* 业务处理器
*/
dataConstructor = {
[MsgType.HELLO]: helloConstructor,
[MsgType.HEART_BEAT]: heartBeatConstructor,
[MsgType.CHAT]: chatConstructor
}
/**
* 构造函数
*/
@@ -132,16 +141,7 @@ class WsConnect {
onOpen(evt) {
console.log('onOpen', evt)
const header = Header.create({
magic: proto.magic,
version: proto.version,
msgType: MsgType.HELLO,
isExtension: false
})
const hello = Msg.create({ header: header })
const payload = Msg.encode(hello).finish()
const data = this.encodePayload(payload)
this.connect.send(data)
this.connect.send(helloConstructor())
}
async onMessage(evt) {
@@ -217,7 +217,7 @@ class WsConnect {
const fromId = msg.body.fromId
const toId = msg.body.toId
const msgType = MsgType.CHAT
const msgTime = new Date() // TODO 这个时间应该是要从消息里面解出来的,但是服务端没有定义这个字段
const msgTime = new Date()
const content = msg.body.content
const msgData = messageStore()
@@ -234,25 +234,6 @@ class WsConnect {
this.events.delivered(msg)
}
/**
* 发送前对长度编码配合服务端解决半包黏包问题
* @param {*} payload
* @returns
*/
encodePayload(payload) {
let num = payload.length
let lenEncode = []
while (num > 0) {
let byte = num & 0x7f
num >>= 7
if (num > 0) {
byte |= 0x80
}
lenEncode.push(byte)
}
return Uint8Array.of(...lenEncode, ...payload)
}
/**
* 数据解码其中解决了半包黏包问题
* @param {*} data
@@ -315,34 +296,21 @@ class WsConnect {
}
/**
* 发送msg封装了重发机制 TODO 这个函数要按照消息类型拆出来多个
* @param {*} toId
* 发送msg封装了重发机制
* @param {*} remoteId 对方id或者群id
* @param {*} msgType
* @param {*} content
* @param {*} callback
*/
sendMsg(toId, msgType, content, callback) {
const header = Header.create({
magic: proto.magic,
version: proto.version,
msgType: msgType,
isExtension: false
})
const userData = userStore()
const body = Body.create({
fromId: userData.user.account,
fromClient: userData.clientId,
toId: toId,
seq: 1,
ack: 1,
content: content,
tempMsgId: 1
})
const chatMsg = Msg.create({ header: header, body: body })
const payload = Msg.encode(chatMsg).finish()
const data = this.encodePayload(payload)
sendMsg(remoteId, msgType, content, callback) {
const data = this.dataConstructor[msgType](remoteId, content)
this.sendAgent(data, callback)
}
/**
* 发送代理封装了重发机制
*/
sendAgent(data, callback) {
if (this.isConnect) {
this.bindEvent('delivered', callback)
this.connect.send(data)
@@ -353,7 +321,7 @@ class WsConnect {
// TODO 应该反馈到业务层给提示
} else {
setTimeout(() => {
this.sendMsg(data, callback)
this.sendAgent(data, callback)
}, this.reSend.interval)
this.reSend.curReSendTimes++
}
@@ -369,18 +337,8 @@ class WsConnect {
this.isConnect = false
this.reconnect.start()
} else {
const header = Header.create({
magic: proto.magic,
version: proto.version,
msgType: MsgType.HEART_BEAT,
isExtension: false
})
const heartBeat = Msg.create({ header: header })
const payload = Msg.encode(heartBeat).finish()
const data = this.encodePayload(payload)
this.connect.send(data)
this.connect.send(heartBeatConstructor())
this.heartBeat.healthPoint++
// console.log('send heart beat, the health point is: ', this.heartBeat.healthPoint)
}
}

View File

@@ -13,7 +13,7 @@ import router from '@/router'
import MyCard from '@/components/navigate/MyCard.vue'
import NaviMenu from '@/components/navigate/NaviMenu.vue'
import { userLogoutService } from '@/api/user'
import wsConnect from '@/api/wsConnect'
import wsConnect from '@/js/websocket/wsConnect'
const myCardDialog = ref()
const myAvatar = ref()

View File

@@ -25,7 +25,7 @@ import { userStore, settingStore, messageStore } from '@/stores'
import backgroupImage from '@/assets/messagebx_bg.webp'
import { msgChatSessionListService } from '@/api/message'
import { MsgType } from '@/proto/msg'
import wsConnect from '@/api/wsConnect'
import wsConnect from '@/js/websocket/wsConnect'
const userData = userStore()
const settingData = settingStore()
@@ -136,11 +136,11 @@ const handleExportData = (data) => {
// 发送事件要做的事情
const handleExportContent = (content) => {
// TODO 这里还要考虑失败情况1消息发不出去2消息发出去了服务器不发“已发送”
wsConnect.sendMsg(curObject.value.account, MsgType.CHAT, content, (deliveredMsg) => {
wsConnect.sendMsg(showId.value, curSessionType.value, content, (deliveredMsg) => {
messageData.addMsgRecord(curSessionId.value, {
msgId: deliveredMsg.body.msgId,
fromId: userData.user.account,
msgType: MsgType.CHAT, // TODO 这里应该是读取sessionType但是sessionType没有按照MsgType写
msgType: curSessionType.value,
msgTime: new Date(),
content: content
})