You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

318 lines
8.3 KiB

2 months ago
import Vue from "vue";
import GLOBAL_OBJ from "./global";
import "./EventHub";
import { setMsgData } from "./message";
// 心跳间隔
2 months ago
const HEART_BEAT_TIME = 15000;
2 months ago
// 心跳最大失败次数(超过此次数重连)
const HEART_BEAT_FAIL_NUM = 1;
// 重连间隔
const RECONNECT_TIME = 1000;
export default class Socket {
constructor(option) {
this.socket = null;
this._options = option;
this.timeoutObj = null;
this.robotObj = {};
this.selfCloseStatus = false
this.reconnectLock = false
console.log("Socket init", GLOBAL_OBJ);
2 months ago
// 失败回答
this.failMsg = {}
2 months ago
}
getToken() {
return new Promise((resolve, reject) => {
2 months ago
console.log('-----开始请求token-----')
2 months ago
uni.request({
method: "GET",
dataType: "json",
// url: `http://192.168.124.118:8083/xcx/framework/agent/${this._options.agentId}`,
url: `https://des.js-dyyj.com/getDemoToken?id=${this._options.agentId}`,
success: (res) => {
console.log("请求token成功", res);
resolve(res);
},
fail: (err) => {
wx.showToast({
title: "创建失败",
icon: "none",
});
console.log("请求token失败", err);
reject()
},
});
});
}
async init() {
return this.createSocket();
}
async createSocket(options) {
return new Promise(async (resolve, reject) => {
const origin = "wss://wss.lke.cloud.tencent.com";
let path = "/v1/qbot/chat/conn/";
let initSocket = 1;
let mainToken
const res = await this.getToken();
if (
res &&
res.data &&
res.data.apiResponse &&
res.data.apiResponse.Token
) {
mainToken = res.data.apiResponse.Token;
}
// 机器人信息
this.robotObj = res.data.requestInfo;
console.log("获取token:", mainToken);
// 建立连接
const socket = wx.connectSocket({
url: `${origin}${path}?EIO=4&transport=websocket`,
success: (e) => {
2 months ago
console.log("创建长链接成功", e);
2 months ago
},
complete: (e) => {
console.log("socket - complete", e);
},
});
this.socket = socket;
GLOBAL_OBJ.SOCKET = this;
let systemEventEmit = (eventName, data) => {
Vue.prototype.$eventHub.$emit(eventName, data);
};
socket.onOpen((e) => {
// 监听发送
if (initSocket === 1) {
const token = mainToken || "";
if (token) {
// cb({ token: token });
this.send({
data:
"40" +
JSON.stringify({
token: token,
}),
});
} else {
// cb({ token: '' });
this.send({
data: JSON.stringify({
token: "",
}),
});
}
initSocket++;
} else {
const token = mainToken || "";
// cb({ token: token });
this.send({
data: JSON.stringify({
token: token,
}),
});
initSocket++;
}
options && options.complete && options.complete()
});
socket.onMessage((e) => {
// console.log("socket.onMessage", e);
const { data } = e;
if (data == 2) {
// 触发浪涌
this.send({
data: 3,
});
}
const params = this.getMsgData(data);
const { type } = params ?? {};
this.on(type, params);
if (params && params.type === "reply" && !params.is_from_self) {
// 回复消息
this._options.onMessage && this._options.onMessage(params);
}
const num = "" + data.substring(0, 2);
if (num == "40") {
2 months ago
console.log("创建对话成功", e);
// 发送失败信息
this.sendFailMsg()
2 months ago
resolve();
2 months ago
// 链接成功
2 months ago
}
this.createInter();
});
// 失败
socket.onError((e) => {
console.log("websocket error 长链接报错", e);
// 失败重建
this.doConnectTimeout();
//
});
// 关闭
socket.onClose((e) => {
console.log("websocket close 长链接关闭", e);
this.connectSocketTimeOut && clearTimeout(this.connectSocketTimeOut);
//非自动关闭重连
if (e.code == 1006) {
this.doConnectTimeout();
}
});
});
}
doConnectTimeout() {
// 重连一次
2 months ago
console.log("websocket 异常关闭 开始重连");
this.connectSocketTimeOut = setTimeout(() => {
2 months ago
this.createSocket({
complete: function (res) {
2 months ago
// this.reconnectLock = false;
2 months ago
},
});
}, RECONNECT_TIME);
}
onConnect(e) {
console.log("websocket connect", e);
}
send(e, t) {
2 months ago
console.log("开始请求 websocket send", e);
2 months ago
this.socket && this.socket.send(e);
this.createInter();
}
2 months ago
sendFailMsg() {
const content = Object.values(this.failMsg)
if (content.length) {
console.log('开始重新发送失败信息')
// 重新发送失败的信息
for (let index = 0; index < content.length; index++) {
const item = content[index];
if (!item.status) {
console.log('失败消息', item)
// 失败消息 在发送一遍
this.send(item.data.socketParams,item.data.contentType )
}
}
}
}
2 months ago
getMsgData(e) {
if (e && typeof e == "string") {
const status = e.indexOf("42");
const index = e.indexOf("[");
if (status > -1 && index > -1) {
const txt = e.substring(index);
const item = JSON.parse(txt);
const [type, obj] = item;
const payload = obj.payload ? obj.payload : {};
const params = {
chatId: this._options.agentId,
type,
contentType: "text", //默认文字
timestamp: new Date().getTime(),
...payload,
};
// 缓存聊天记录
return params;
}
}
return null;
}
emit(type, params, contentType) {
console.log("emit", type, params);
const data = {
payload: params,
};
switch (type) {
case "send":
// 发送消息
const socketParams = { data: "42" + JSON.stringify(["send", data]) };
this.send(socketParams, contentType);
console.log(params.request_id + '发送内容', data)
if (!params.is_msg_status) {
// 不写入缓存中
return;
}
const msgParams = {
chatId: this._options.agentId,
contentType,
type,
timestamp: new Date().getTime(),
...params,
content: params.realContent ? params.realContent : params.content,
};
msgParams && setMsgData(msgParams);
2 months ago
this.failMsg[params.request_id] = {
data: {
socketParams,
contentType
},
statue: false
}
2 months ago
break;
}
}
// 监听
on(type, params) {
switch (type) {
case "reply":
// 回复结束
const tmpParams = {
...params,
name: this.robotObj.name,
headImage: this.robotObj.headImage,
};
if (
params &&
params.type === "reply" &&
!params.is_from_self &&
params.can_rating
) {
// 回复消息
this._options.onMessage && this._options.onMessage(tmpParams);
}
if (!params.is_from_self && params.is_final) {
2 months ago
if (this.failMsg[tmpParams.request_id]) {
this.failMsg[tmpParams.request_id].status = true
// 已回复 状态为true
}
2 months ago
// 回复结束 写入缓存
setMsgData(tmpParams);
}
// 回复
break;
}
}
// 关闭socket
destroy() {
if (this.socket && this.socket.readyState == 1) {
this.socket && this.socket.close();
this.socket = null;
}
2 months ago
this.failMsg={}
2 months ago
}
createInter() {
if (this.timeoutObj) {
clearTimeout(this.timeoutObj);
}
this.timeoutObj = setTimeout(() => {
this.socket && this.socket.send && this.socket.send({ data: 3 });
}, HEART_BEAT_TIME);
}
}