node-socket-rpc
Advanced tools
Comparing version 1.0.0 to 1.0.1
@@ -11,2 +11,3 @@ "use strict"; | ||
const cron_1 = require("cron"); | ||
const uuid_1 = __importDefault(require("uuid")); | ||
const utils_1 = require("./utils"); | ||
@@ -30,3 +31,3 @@ class NClient { | ||
this.events = new Map(); | ||
this.timer = null; | ||
this.callEvents = new Map(); | ||
this._heart = () => { | ||
@@ -72,4 +73,20 @@ if (this.info.closed) | ||
} | ||
if (data.command === utils_1.CommandEnum.CALL) { | ||
return this._callBack(data.data); | ||
} | ||
this.execRoute(data); | ||
}; | ||
/** | ||
* 定时清除超时的调用事件 | ||
*/ | ||
this._checkCall = () => { | ||
const now = Date.now(); | ||
this.callEvents.forEach((v, k) => { | ||
if (now - v.time > 30000) { | ||
const promiseData = v; | ||
promiseData.reject("等待超时"); | ||
this.callEvents.delete(k); | ||
} | ||
}); | ||
}; | ||
if (opts) { | ||
@@ -82,4 +99,6 @@ for (const key in opts) { | ||
this.loger = utils_1.createLog(this.cfg.debug); | ||
this.timer = new cron_1.CronJob("*/5 * * * * *", this._heart).start(); | ||
new cron_1.CronJob("*/5 * * * * *", this._heart).start(); | ||
new cron_1.CronJob("0 * * * * *", this._checkCall).start(); | ||
} | ||
// private timer = null; | ||
/** | ||
@@ -207,4 +226,35 @@ * 开始监听远程服务 | ||
} | ||
/** | ||
* 远程调用 | ||
* @param method 方法名 | ||
*/ | ||
call(method, params) { | ||
const eventId = uuid_1.default.v4() + ""; | ||
this.loger("远程调用", method); | ||
return new Promise((resolve, reject) => { | ||
this.send(utils_1.CommandEnum.CALL, { method, eventId, params }); | ||
this.callEvents.set(eventId, { resolve, reject, time: Date.now() }); | ||
}); | ||
} | ||
/** | ||
* 远程调用的回调 | ||
* @param data 数据 | ||
*/ | ||
_callBack(data) { | ||
const eventId = data.eventId; | ||
if (!eventId) | ||
return; | ||
const promiseData = this.callEvents.get(eventId); | ||
if (!promiseData) | ||
return; | ||
if (data.error) { | ||
promiseData.reject(data.error); | ||
} | ||
else { | ||
promiseData.resolve(data.success); | ||
} | ||
this.callEvents.delete(eventId); | ||
} | ||
} | ||
exports.NClient = NClient; | ||
exports.default = NClient; |
@@ -24,2 +24,4 @@ "use strict"; | ||
this.clients = new Map(); | ||
//注册的方法 | ||
this.callEvents = new Map(); | ||
/** | ||
@@ -121,2 +123,5 @@ * 建立新的连接时 | ||
} | ||
if (data.command === utils_1.CommandEnum.CALL) { | ||
return this.onCall(uid, data.data); | ||
} | ||
} | ||
@@ -205,3 +210,55 @@ /** | ||
} | ||
/** | ||
* 当客户端要远程调用服务端注册的方法的时候 | ||
* @param data 数据 | ||
*/ | ||
async onCall(uid, data) { | ||
const method = data.method; | ||
const eventId = data.eventId; | ||
const params = data.params; | ||
if (!method || !eventId) | ||
return; | ||
const fn = this.callEvents.get(method); | ||
if (!fn) { | ||
return this.callBack(uid, eventId, null, "方法不存在"); | ||
} | ||
try { | ||
const res = await fn(params); | ||
this.callBack(uid, eventId, res); | ||
} | ||
catch (error) { | ||
this.callBack(uid, eventId, null, error.message); | ||
} | ||
} | ||
/** | ||
* 调起回调方法 | ||
* @param uid uid | ||
* @param eventId 事件id | ||
* @param success 成功结果 | ||
* @param error 失败结果 | ||
*/ | ||
callBack(uid, eventId, success, error) { | ||
if (error) { | ||
this.sendTo(uid, utils_1.CommandEnum.CALL, { | ||
eventId, | ||
error, | ||
}); | ||
} | ||
else { | ||
this.sendTo(uid, utils_1.CommandEnum.CALL, { | ||
eventId, | ||
success, | ||
}); | ||
} | ||
} | ||
/** | ||
* 注册方法 | ||
* @param method 方法名 | ||
* @param fn 方法 | ||
*/ | ||
regMethod(method, fn) { | ||
this.callEvents.set(method, fn); | ||
} | ||
} | ||
exports.NServer = NServer; | ||
exports.default = NServer; | ||
@@ -208,0 +265,0 @@ /** |
@@ -61,2 +61,6 @@ "use strict"; | ||
CommandEnum["NOTICE"] = "_notice"; | ||
/** | ||
* 远程调用方法 | ||
*/ | ||
CommandEnum["CALL"] = "_call"; | ||
})(CommandEnum = exports.CommandEnum || (exports.CommandEnum = {})); | ||
@@ -63,0 +67,0 @@ /** |
{ | ||
"name": "node-socket-rpc", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "使用nodejs开发的socket通讯RPC", | ||
@@ -5,0 +5,0 @@ "main": "src/index.ts", |
# node-socket | ||
使用 nodejs 开发的 socket 通讯,目前支持 tcp 协议。 | ||
使用 nodejs 开发的 socket 通讯,目前支持 tcp 协议。基本功能:断线重连、心跳检测、路由、远程调用、超时监听等。 | ||
支持客户端监听服务端的通知、事件。使用路由方式在客户端监听。 | ||
支持远程调用。服务端注册方法,客户端调用方法即可。 | ||
## 功能 | ||
@@ -62,2 +66,3 @@ | ||
9. `use(routeName:string, fn:any)`。路由事件。 | ||
10. `call(method: string)`。远程调用方法 | ||
@@ -73,1 +78,2 @@ ## 包含的功能 | ||
7. 客户端发送消息到客户端,发送房间消息 | ||
8. 远程调用。服务端注册方法,客户端调用 |
@@ -6,3 +6,4 @@ /** | ||
import { CronJob } from "cron"; | ||
import { ICommandData, CommandEnum, ToBuff, ToData, createLog } from "./utils"; | ||
import uuid from "uuid"; | ||
import { ICommandData, CommandEnum, ToBuff, ToData, createLog, ICallBackData } from "./utils"; | ||
@@ -41,3 +42,4 @@ interface IClientOpts { | ||
this.loger = createLog(this.cfg.debug); | ||
this.timer = new CronJob("*/5 * * * * *", this._heart).start(); | ||
new CronJob("*/5 * * * * *", this._heart).start(); | ||
new CronJob("0 * * * * *", this._checkCall).start(); | ||
} | ||
@@ -62,2 +64,3 @@ | ||
private events: Map<string, any> = new Map(); | ||
private callEvents: Map<string, any> = new Map(); | ||
/** | ||
@@ -67,3 +70,3 @@ * 内部的socket对象 | ||
private socket: net.Socket | undefined; | ||
private timer = null; | ||
// private timer = null; | ||
/** | ||
@@ -148,2 +151,5 @@ * 开始监听远程服务 | ||
} | ||
if (data.command === CommandEnum.CALL) { | ||
return this._callBack(data.data); | ||
} | ||
this.execRoute(data); | ||
@@ -233,3 +239,44 @@ }; | ||
} | ||
/** | ||
* 远程调用 | ||
* @param method 方法名 | ||
*/ | ||
call(method: string, params?: any): Promise<any> { | ||
const eventId: string = uuid.v4() + ""; | ||
this.loger("远程调用", method); | ||
return new Promise((resolve, reject) => { | ||
this.send(CommandEnum.CALL, { method, eventId, params }); | ||
this.callEvents.set(eventId, { resolve, reject, time: Date.now() }); | ||
}); | ||
} | ||
/** | ||
* 远程调用的回调 | ||
* @param data 数据 | ||
*/ | ||
private _callBack(data: ICallBackData) { | ||
const eventId = data.eventId; | ||
if (!eventId) return; | ||
const promiseData = this.callEvents.get(eventId); | ||
if (!promiseData) return; | ||
if (data.error) { | ||
promiseData.reject(data.error); | ||
} else { | ||
promiseData.resolve(data.success); | ||
} | ||
this.callEvents.delete(eventId); | ||
} | ||
/** | ||
* 定时清除超时的调用事件 | ||
*/ | ||
private _checkCall = () => { | ||
const now = Date.now(); | ||
this.callEvents.forEach((v, k) => { | ||
if (now - v.time > 30000) { | ||
const promiseData = v; | ||
promiseData.reject("等待超时"); | ||
this.callEvents.delete(k); | ||
} | ||
}); | ||
}; | ||
} | ||
export default NClient; |
@@ -16,3 +16,3 @@ /** | ||
} | ||
export default class NServer { | ||
export class NServer { | ||
constructor(opts?: IServerCfg) { | ||
@@ -42,2 +42,4 @@ if (opts) { | ||
private clients: Map<string, OneClient> = new Map(); | ||
//注册的方法 | ||
private callEvents: Map<string, any> = new Map(); | ||
/** | ||
@@ -118,2 +120,5 @@ * 启动监听 | ||
} | ||
if (data.command === CommandEnum.CALL) { | ||
return this.onCall(uid, data.data); | ||
} | ||
} | ||
@@ -211,3 +216,57 @@ /** | ||
} | ||
/** | ||
* 当客户端要远程调用服务端注册的方法的时候 | ||
* @param data 数据 | ||
*/ | ||
private async onCall(uid: string, data: ICallData) { | ||
const method = data.method; | ||
const eventId = data.eventId; | ||
const params = data.params; | ||
if (!method || !eventId) return; | ||
const fn = this.callEvents.get(method); | ||
if (!fn) { | ||
return this.callBack(uid, eventId, null, "方法不存在"); | ||
} | ||
try { | ||
const res = await fn(params); | ||
this.callBack(uid, eventId, res); | ||
} catch (error) { | ||
this.callBack(uid, eventId, null, error.message); | ||
} | ||
} | ||
/** | ||
* 调起回调方法 | ||
* @param uid uid | ||
* @param eventId 事件id | ||
* @param success 成功结果 | ||
* @param error 失败结果 | ||
*/ | ||
private callBack(uid: string, eventId: string, success: any, error?: any) { | ||
if (error) { | ||
this.sendTo(uid, CommandEnum.CALL, { | ||
eventId, | ||
error, | ||
}); | ||
} else { | ||
this.sendTo(uid, CommandEnum.CALL, { | ||
eventId, | ||
success, | ||
}); | ||
} | ||
} | ||
/** | ||
* 注册方法 | ||
* @param method 方法名 | ||
* @param fn 方法 | ||
*/ | ||
regMethod(method: string, fn: any) { | ||
this.callEvents.set(method, fn); | ||
} | ||
} | ||
export default NServer; | ||
interface ICallData { | ||
method: string; | ||
eventId: string; | ||
params?: any; | ||
} | ||
/** | ||
@@ -214,0 +273,0 @@ * 单独的客户端管理类 |
@@ -63,2 +63,6 @@ export interface ICommandData { | ||
NOTICE = "_notice", | ||
/** | ||
* 远程调用方法 | ||
*/ | ||
CALL = "_call", | ||
} | ||
@@ -104,1 +108,7 @@ | ||
} | ||
export interface ICallBackData { | ||
eventId: string; | ||
success?: any; | ||
error?: any; | ||
} |
@@ -9,15 +9,9 @@ const { NClient } = require("../dist/NClient"); | ||
console.log("监听端口", 18000); | ||
const sleep = (time) => new Promise((resolve) => setTimeout(() => resolve(), time)); | ||
ct.use("test", async function (data) { | ||
console.log("1", data); | ||
await sleep(3000); | ||
console.log("1_end"); | ||
return data + 1; | ||
}); | ||
// ct.use("test", async function (data) { | ||
// console.log("2", data); | ||
// await sleep(2000); | ||
// console.log("2_end"); | ||
// return data + 1; | ||
// }); | ||
//远程调用服务端方式 | ||
async function main() { | ||
const data = await ct.call("test.test"); | ||
console.log("远程调用", data); | ||
} | ||
setTimeout(() => { | ||
main(); | ||
}, 3000); |
@@ -10,2 +10,4 @@ import { NClient } from "../src/NClient"; | ||
const sleep = (time: number) => new Promise((resolve) => setTimeout(() => resolve(), time)); | ||
//服务端通知路由方式 | ||
ct.use("test", async function (data) { | ||
@@ -24,1 +26,2 @@ console.log("1", data); | ||
}); | ||
48201
20
1491
78