加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
index.ts 6.28 KB
一键复制 编辑 原始数据 按行查看 历史
tmkmk 提交于 2021-02-27 23:53 . 初步测试
import { uuid, isStringT, isNst, isInt, sleep, isNumber } from "@mac-xiang/method";
// import * as io from "weapp.socket.io";
const io = require("weapp.socket.io");
declare function parseInt(s: string | number, radix?: number): number;
type ns = number | string;
interface oa { [porp: string]: any; };
interface fun { (param: any): any; }
interface of { [porp: string]: fun; };
export interface websocket {
on: { (event: string, callback: fun): websocket; };
emit: { (method: string, data: any): void; };
}
export interface MSG {
time: number; // 当前时间 一般取值 new Date().getTime()
type: string; // 当前消息类型
source: ns; // 发送人的id
content: string; // 发送内容
con: string; // 发送的会话id
users?: ns[];
result?: any;
callback?: string;
// [prop: string]: any;
}
export function getNSa(p: any): ns[] | undefined {
if (Array.isArray(p)) {
const r: ns[] = [];
p.forEach(a => {
if (isInt(a) || isStringT(a)) {
r.push(a);
}
});
if (r.length) return r;
}
}
export function toMSG(p: any): MSG | undefined {
if (
p &&
isStringT(p.type) &&
isNst(p.source)
) {
const r: MSG = {
time: parseInt(Date.now() / 1000),
type: p.type,
source: p.source,
content: typeof p.content == "string" ? p.content : "",
con: p.con,
result: p.result,
callback: p.callback
};
const u = getNSa(p.users);
if (u) r.users = u;
return r;
}
};
export interface createTmkSocket {
address: string; // 服务器地址
token: string; // 服务器认证信息
reconnect?: number; // 重新连接尝试次数; 小于0 永远尝试连接;0|undefind 不重新连接.
reTime?: number; // 重新连接间隔;最小值5000毫秒
callback?: fun; // 连接成功后回调
eventFuns?: of; // 需要覆盖监听的事件函数集合
}
export const history: oa = {}, clients: ns[] = [],
callbacks: {
[porp: string]: {
timeout: number;
callback: fun;
param?: any;
};
} = {},
events: oa = {}, ioEvent = ["recv", "join"];
function clearCallbacks() {
const time = Date.now();
Object.keys(callbacks).forEach(k => {
if (!(callbacks[k].timeout > time)) {
try {
callbacks[k].callback({ err: "超时" });
} catch (error) { }
delete callbacks[k];
}
});
}
setInterval(() => {
try {
clearCallbacks();
} catch (error) { }
}, 2000);
export function callbackEvent(d: MSG, event = "recv") {
if (d.callback) {
if (callbacks[d.callback]) {
callbacks[d.callback].callback(d);
delete callbacks[d.callback];
}
} else if (events[event]) Object.keys(events[event]).map(k => { events[event][k](d); });
}
let socket: websocket;
export class tmkSocket {
socket: websocket;
constructor (param: createTmkSocket) {
this.cs(param);
}
private async cs(param: createTmkSocket) {
if (!param.eventFuns) param.eventFuns = {};
if (typeof param.reconnect != "number") param.reconnect = 0;
if (!isNumber(param.reTime) || !param.reTime) param.reTime = 0;
if (param.reTime > 0 && param.reTime < 5000) param.reTime = 5000;
let s: any;
s = await this.createSocket(param.address, param.token, param.eventFuns);
if (s) {
this.socket = s;
socket = s;
} else {
await sleep(param.reTime);
if (param.reconnect < 0 || param.reconnect-- > 0) this.cs(param);
}
}
private createSocket(addr: string, token: string, funs: of) {
return new Promise<websocket | void>((resolve) => {
const keys = Object.keys(funs);
const socket: websocket = io(addr, { query: { token } });
if (keys.indexOf("method") < 0) socket.on("method", this.method);
if (keys.indexOf("message") < 0) socket.on("message", this.message);
if (keys.indexOf("join") < 0) socket.on("join", this.join);
keys.forEach(k => { socket.on(k, funs[k]); });
socket.on("error", () => { resolve(); });
socket.on("connect", () => { resolve(socket); });
});
}
private method(d: MSG) {
switch (d.type) {
case "con":
if (d.result) {
history[d.con] = d.result;
}
break;
case "join":
if (d.result && d.con) history[d.con] = d.result;
break;
case "login":
if (d.result) {
Object.assign(history, d.result.history);
} else {
console.log("登录失败", d);
}
break;
default:
console.log("method", d);
return;
}
callbackEvent(d);
}
private message(d: MSG) {
if (!history[d.con]) history[d.con] = [];
history[d.con].push(d);
callbackEvent(d);
}
private join(d: MSG) {
if (d.source && clients.indexOf(d.source) < 0) {
clients.push(d.source);
}
callbackEvent(d, "join");
}
send(data: MSG, method: string) {
return send(data, method);
}
}
export function send(data: MSG, method: string) {
return new Promise((resolve) => {
if (method != "method") method = "message";
data.callback = uuid;
callbacks[data.callback] = {
callback: resolve,
timeout: +new Date + 10000
};
socket.emit(method, data);
});
}
export default tmkSocket;
// VueComponent
// import Vue from "vue";
// Vue.mixin({
// created() {
// const that: any = this;
// if (that.$options && that.$options.events) {
// Object.keys(that.$options.events).forEach(key => {
// let handler = that.$options.events[key];
// if (typeof handler === 'string') {
// handler = that[handler];
// }
// that[key + '::handler'] = handler.bind(that);
// that.$root.$on(key, that[key + '::handler']);
// if (ioEvent.indexOf(key) >= 0) {
// if (!that.events) that.events = {};
// that.events[key] = uuid;
// if (!events[key]) events[key] = {};
// events[key][that.events[key]] = that[key + '::handler'];
// }
// });
// }
// },
// beforeDestroy() {
// const that: any = this;
// if (that.$options && that.$options.events) {
// Object.keys(that.$options.events).forEach(key => {
// that.$root.$off(key, that[key + '::handler']);
// if (ioEvent.indexOf(key) >= 0) {
// Object.keys(events[key]).map(k => {
// delete events[key][k];
// });
// }
// });
// }
// }
// });
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化