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.
315 lines
8.3 KiB
315 lines
8.3 KiB
import Vue from "vue";
|
|
import GLOBAL_OBJ from "./global";
|
|
import "./EventHub";
|
|
import { setMsgData } from "./message";
|
|
// 心跳间隔
|
|
const HEART_BEAT_TIME = 15000;
|
|
// 心跳最大失败次数(超过此次数重连)
|
|
const HEART_BEAT_FAIL_NUM = 1;
|
|
// 重连间隔
|
|
const RECONNECT_TIME = 3000;
|
|
|
|
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);
|
|
// 失败回答
|
|
this.failMsg = {}
|
|
}
|
|
getToken() {
|
|
return new Promise((resolve, reject) => {
|
|
console.log('-----开始请求token-----')
|
|
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}`,
|
|
url: `https://des.dayunyuanjian.cn/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";
|
|
// const origin = "wss://des.dayunyuanjian.cn";
|
|
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) => {
|
|
console.log("创建长链接成功", e);
|
|
},
|
|
complete: (e) => {
|
|
console.log("socket - complete", e);
|
|
|
|
},
|
|
});
|
|
this.socket = socket;
|
|
GLOBAL_OBJ.SOCKET = this;
|
|
|
|
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);
|
|
const num = "" + data.substring(0, 2);
|
|
if (num == "40") {
|
|
console.log("创建对话成功", e);
|
|
// 发送失败信息
|
|
this.sendFailMsg()
|
|
resolve();
|
|
// 链接成功
|
|
}
|
|
|
|
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 != 1000) {
|
|
this.doConnectTimeout();
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
doConnectTimeout() {
|
|
if (this.selfCloseStatus){
|
|
// 主动退出 不在重连
|
|
return
|
|
}
|
|
// 重连一次
|
|
console.log("websocket 异常关闭 开始重连");
|
|
this.connectSocketTimeOut = setTimeout(() => {
|
|
this.createSocket({
|
|
complete: function (res) {
|
|
// this.reconnectLock = false;
|
|
},
|
|
});
|
|
}, RECONNECT_TIME);
|
|
}
|
|
|
|
onConnect(e) {
|
|
console.log("websocket connect", e);
|
|
}
|
|
|
|
send(e, t) {
|
|
console.log("开始请求 websocket send", e);
|
|
this.socket && this.socket.send(e);
|
|
this.createInter();
|
|
}
|
|
|
|
sendFailMsg() {
|
|
const content = Object.values(this.failMsg)
|
|
const lastFailMsgIndex = content.findLastIndex(it => !it.status)
|
|
if (lastFailMsgIndex > -1) {
|
|
const msg = content[lastFailMsgIndex]
|
|
console.log('开始重新发送失败信息', msg)
|
|
// 重新发送失败的信息
|
|
this.send(msg.data.socketParams,msg.data.contentType)
|
|
}
|
|
}
|
|
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 tmpParams = params
|
|
tmpParams.incremental = true
|
|
const data = {
|
|
//incremental:true,
|
|
payload: tmpParams
|
|
|
|
};
|
|
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);
|
|
this.failMsg[params.request_id] = {
|
|
data: {
|
|
socketParams,
|
|
contentType
|
|
},
|
|
statue: false
|
|
}
|
|
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
|
|
) {
|
|
// 回复消息
|
|
console.log('reply回复内容', tmpParams.content, tmpParams)
|
|
this._options.onMessage && this._options.onMessage(tmpParams);
|
|
}
|
|
|
|
if (!params.is_from_self && params.is_final) {
|
|
if (this.failMsg[tmpParams.request_id]) {
|
|
this.failMsg[tmpParams.request_id].status = true
|
|
// 已回复 状态为true
|
|
}
|
|
|
|
// 回复结束 写入缓存
|
|
// setMsgData(tmpParams);
|
|
}
|
|
// 回复
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 关闭socket
|
|
destroy() {
|
|
if (this.socket && this.socket.readyState == 1) {
|
|
this.socket && this.socket.close();
|
|
this.socket = null;
|
|
}
|
|
this.failMsg={}
|
|
}
|
|
|
|
createInter() {
|
|
if (this.timeoutObj) {
|
|
clearTimeout(this.timeoutObj);
|
|
}
|
|
return
|
|
this.timeoutObj = setTimeout(() => {
|
|
this.socket && this.socket.send && this.socket.send({ data: 3 });
|
|
}, HEART_BEAT_TIME);
|
|
}
|
|
}
|
|
|