|
|
|
|
/*
|
|
|
|
|
* @Author: ch
|
|
|
|
|
* @Date: 2022-05-18 14:54:47
|
|
|
|
|
* @LastEditors: ch
|
|
|
|
|
* @LastEditTime: 2022-05-20 11:25:57
|
|
|
|
|
* @Description: file content
|
|
|
|
|
*/
|
|
|
|
|
const connect = Symbol('connect'),
|
|
|
|
|
send = Symbol('send');
|
|
|
|
|
|
|
|
|
|
export default class MsbIm {
|
|
|
|
|
option = {
|
|
|
|
|
ioKey : 'traceId',
|
|
|
|
|
reconnect: true,
|
|
|
|
|
}
|
|
|
|
|
socket = null;
|
|
|
|
|
queue = {};
|
|
|
|
|
interceptors = {
|
|
|
|
|
dataChangeBefore: null,
|
|
|
|
|
dataChangeAfter: null,
|
|
|
|
|
onMessage: null,
|
|
|
|
|
onResponse: null
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
sessionData = [];
|
|
|
|
|
curSession = {};
|
|
|
|
|
|
|
|
|
|
constructor(option) {
|
|
|
|
|
this.option = {
|
|
|
|
|
...this.option,
|
|
|
|
|
...option
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 创建连接返回一个Promise 创建成功并成功打开连接算连接成功
|
|
|
|
|
* @param {*} option
|
|
|
|
|
*/
|
|
|
|
|
[connect](option) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
this.socket = uni.connectSocket({
|
|
|
|
|
...option,
|
|
|
|
|
fail(e){
|
|
|
|
|
reject(e);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
this.socket.onOpen(() => {
|
|
|
|
|
this.socket.onMessage((res) => {
|
|
|
|
|
const result = JSON.parse(res.data);
|
|
|
|
|
// 每次消息推送都会推送至onMessage Hook中
|
|
|
|
|
this.interceptors.onMessage && this.interceptors.onMessage(result);
|
|
|
|
|
|
|
|
|
|
// 查看是否有返回信息处理Hook,有的话优先取处理后的结果返回
|
|
|
|
|
const responseData = this.interceptors.onResponse ? this.interceptors.onResponse(result) : result;
|
|
|
|
|
const isError = responseData.constructor === Promise;
|
|
|
|
|
// 如果再消息堆里有此消息回调,则执行回调,并删除
|
|
|
|
|
const cbk = this.queue[result[this.option.ioKey]];
|
|
|
|
|
if (cbk) {
|
|
|
|
|
cbk(isError ? {error:responseData} : {result:responseData});
|
|
|
|
|
delete this.queue[result[this.option.ioKey]];
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
resolve(this.socket);
|
|
|
|
|
});
|
|
|
|
|
this.socket.onClose(() => {
|
|
|
|
|
if (this.option.reconnect) {
|
|
|
|
|
this.connect();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 向服务端发送消息||请求,返回一个Promise对象,收到ioKey对应的消息会算一个同步完成
|
|
|
|
|
* @param {*} data
|
|
|
|
|
*/
|
|
|
|
|
[send](data) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
this.queue[data[this.option.ioKey]] = ({ result, error }) => {
|
|
|
|
|
if (result) {
|
|
|
|
|
resolve(result);
|
|
|
|
|
} else {
|
|
|
|
|
reject(error);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
this.socket.send({
|
|
|
|
|
data : JSON.stringify(data),
|
|
|
|
|
fail(e) {
|
|
|
|
|
if (this.interceptors.onResponse) {
|
|
|
|
|
reject(this.interceptors.onResponse(e))
|
|
|
|
|
}
|
|
|
|
|
reject(e);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 扩展钩子
|
|
|
|
|
* @param {*} hookName
|
|
|
|
|
* @param {*} cb
|
|
|
|
|
*/
|
|
|
|
|
use(hookName, cb){
|
|
|
|
|
this.hook[hookName] = cb;
|
|
|
|
|
}
|
|
|
|
|
init (config) {
|
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
|
const heart = () => {
|
|
|
|
|
setTimeout(async () => {
|
|
|
|
|
await this[send]({
|
|
|
|
|
traceId: CreateUUID(),
|
|
|
|
|
traceType: '0',
|
|
|
|
|
content: { text: "ping" }
|
|
|
|
|
});
|
|
|
|
|
heart();
|
|
|
|
|
},5000)
|
|
|
|
|
}
|
|
|
|
|
this[connect]({
|
|
|
|
|
...config,
|
|
|
|
|
// url : `wss://you-gateway.mashibing.com/ws?client=${store.state.token}&type=1`
|
|
|
|
|
// url : `wss://k8s-horse-gateway.mashibing.cn/ws?client=${store.state.token}&type=1`, // url是websocket连接ip
|
|
|
|
|
|
|
|
|
|
}).then(() => {
|
|
|
|
|
heart();
|
|
|
|
|
resolve(this);
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* 设置
|
|
|
|
|
*/
|
|
|
|
|
setSessionData(data) {
|
|
|
|
|
|
|
|
|
|
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(data, this.sessionData);
|
|
|
|
|
this.sessionData = data;
|
|
|
|
|
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* 设置当前聊天窗口
|
|
|
|
|
* Data为Session数据
|
|
|
|
|
* @param {*} data
|
|
|
|
|
*/
|
|
|
|
|
setCurSession(data) {
|
|
|
|
|
this.curSession = data;
|
|
|
|
|
}
|
|
|
|
|
async getSessionList (params) {
|
|
|
|
|
let {content} = await this[send]({
|
|
|
|
|
traceId: CreateUUID(),
|
|
|
|
|
...params
|
|
|
|
|
});
|
|
|
|
|
content.sessionVOS.forEach(item => {
|
|
|
|
|
if (item.lastMessage) {
|
|
|
|
|
item.lastMessage.createTimeStamp = FormatDate(item.lastMessage.createTimeStamp, 'mm-dd hh:ii')
|
|
|
|
|
item.lastMessage.payload = JSON.parse(item.lastMessage.payload || {});
|
|
|
|
|
}
|
|
|
|
|
let historyData = this.sessionData;
|
|
|
|
|
let hisIndex = historyData.findIndex(i => i.id === item.id);
|
|
|
|
|
if(hisIndex >= 0){
|
|
|
|
|
historyData[hisIndex].lastMessage = item.lastMessage;
|
|
|
|
|
historyData[hisIndex].unreadCount++;
|
|
|
|
|
|
|
|
|
|
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(historyData, this.sessionData);
|
|
|
|
|
this.sessionData = historyData;
|
|
|
|
|
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
|
|
|
|
|
}else{
|
|
|
|
|
item.messageList = [];
|
|
|
|
|
const newData = [...historyData, item]
|
|
|
|
|
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(newData, this.sessionData);
|
|
|
|
|
this.sessionData = newData;
|
|
|
|
|
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
async getHistoryMsg (params){
|
|
|
|
|
let { content } = await this[send]({
|
|
|
|
|
traceId: CreateUUID(),
|
|
|
|
|
traceType : 23,
|
|
|
|
|
...params
|
|
|
|
|
})
|
|
|
|
|
if(!content.length){
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// ctx.reverse();
|
|
|
|
|
let newData = this.sessionData;
|
|
|
|
|
const hisIdx = newData.findIndex(i => i.id === content[0].sessionId);
|
|
|
|
|
content.forEach(item => {
|
|
|
|
|
item.createTimeStamp = FormatDate(item.createTimeStamp, 'mm-dd hh:ii');
|
|
|
|
|
item.payload = JSON.parse(item.payload)
|
|
|
|
|
})
|
|
|
|
|
newData[hisIdx].messageList = newData[hisIdx].messageList.concat(content);
|
|
|
|
|
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(newData, this.sessionData);
|
|
|
|
|
this.sessionData = newData;
|
|
|
|
|
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
|
|
|
|
|
return Promise.resolve(content);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
async setRead (params){
|
|
|
|
|
await this[send]({
|
|
|
|
|
traceId : CreateUUID(),
|
|
|
|
|
traceType : "6",
|
|
|
|
|
...params
|
|
|
|
|
});
|
|
|
|
|
// 计算页头消息数
|
|
|
|
|
this.curSession.unreadCount = 0;
|
|
|
|
|
}
|
|
|
|
|
async sendMsg (params){
|
|
|
|
|
const { content } = await this[send]({
|
|
|
|
|
traceId: CreateUUID(),
|
|
|
|
|
traceType: 20,
|
|
|
|
|
...params
|
|
|
|
|
});
|
|
|
|
|
return Promise.resolve(content)
|
|
|
|
|
}
|
|
|
|
|
async createSession (params){
|
|
|
|
|
const { content } = await this[send]({
|
|
|
|
|
traceId : CreateUUID(),
|
|
|
|
|
traceType : 21,
|
|
|
|
|
...params
|
|
|
|
|
});
|
|
|
|
|
let historyData = this.sessionData;
|
|
|
|
|
let curSession = historyData.find(i => i.id === content.id);
|
|
|
|
|
if (!curSession) {
|
|
|
|
|
curSession = {
|
|
|
|
|
...content,
|
|
|
|
|
unreadCount: 0,
|
|
|
|
|
messageList : []
|
|
|
|
|
}
|
|
|
|
|
const newData = [...historyData, curSession];
|
|
|
|
|
this.interceptors.dataChangeBefore && this.interceptors.dataChangeBefore(newData, this.sessionData);
|
|
|
|
|
this.sessionData = newData;
|
|
|
|
|
this.interceptors.dataChangeAfter && this.interceptors.dataChangeAfter(this.sessionData);
|
|
|
|
|
}
|
|
|
|
|
this.curSession = curSession;
|
|
|
|
|
// store.commit('SET_SESSION_DATA',this.sessionData);
|
|
|
|
|
// store.commit('SET_SESSION_MSG_ID',curSession.id);
|
|
|
|
|
return Promise.resolve(content);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|