二七王:收包分发器与失败回包处理

分发器只分发不写业务。判定顺序上先看 data.success,失败包一律先分流给
FailHandler——协议规定失败回包的 rpc 与请求同名(chupai 失败回 chupai,
成功走 chupai1/2/3),不先分流则每个业务 handler 都要自己判一遍。

未知 rpc 只警告不抛错,畸形入参不崩。路由表完整性断言留待全部 handler 就位。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-27 17:36:15 +08:00
co-authored by Claude Opus 5
parent 65674542b3
commit 01eb6c60b5
3 changed files with 130 additions and 0 deletions
@@ -0,0 +1,51 @@
///////////////////////////////////////////////////////////////
////////// EQW_Dispatcher: 唯一收包入口 + 纯路由表 ////////////
///////////////////////////////////////////////////////////////
// 前端 04 §2:收包统一分发,一 rpc 一处理器。
// 【本文件只分发,不写业务】——新增一种服务端推送 = 注册一条 rpc → handler。
//
// 判定顺序(关键):先看 data.success,为 false 一律交 FailHandler、不进业务 handler。
// 因为协议 §0.2 规定失败回包的 rpc 与【请求】同名(chupai 失败回 chupai,
// 而成功走 chupai1/2/3),不先分流的话每个业务 handler 都得自己判一遍。
var EQW_Dispatcher = EQW_Dispatcher || {
_handlers: {},
//注册一条 rpc → handler
register: function (rpc, handler) {
if (typeof rpc !== 'string' || typeof handler !== 'function') {
throw new Error('[EQW_Dispatcher] register 参数非法: ' + rpc);
}
if (this._handlers.hasOwnProperty(rpc)) {
throw new Error('[EQW_Dispatcher] rpc 重复注册: ' + rpc);
}
this._handlers[rpc] = handler;
},
hasHandler: function (rpc) {
return this._handlers.hasOwnProperty(rpc);
},
//唯一收包入口。msg = { rpc, data }
dispatch: function (msg) {
if (!msg || typeof msg.rpc !== 'string') {
console.warn('[EQW_Dispatcher] 畸形数据包,已忽略');
return;
}
var data = msg.data || {};
//成败只认 data.success(前端 04 §4):失败包一律先分流
if (data.success === false) {
EQW_FailHandler.handle(msg.rpc, data);
return;
}
var h = this._handlers[msg.rpc];
if (h) {
h(data);
} else {
//平台日后新增推送不该让前端崩
console.warn('[EQW_Dispatcher] 未处理的 rpc: ' + msg.rpc);
}
}
};
@@ -0,0 +1,24 @@
///////////////////////////////////////////////////////////////
////////// EQW_FailHandler: 失败回包 //////////////////////////
///////////////////////////////////////////////////////////////
// 协议 §0.2:服务端受理请求时任一校验不通过,回一个【rpc 与请求同名】的失败包,
// data 只含 success:false 与 errcode,且只回给请求者。
//
// errcode(服务端 youle_erqiwang.ERR):
// 1 PLAYER 玩家/房间/座位校验不通过 2 NODESK 牌桌或牌局不存在
// 3 STEP 当前阶段不允许该操作 4 SEAT 位置不符或还没轮到
// 5 PARAM 参数非法 6 RULE 规则不允许
//
// 失败信息是【一次性】的,不属于对局状态,故不进 GameState,只随事件带出去。
var EQW_FailHandler = EQW_FailHandler || {
ERR: {
PLAYER: 1, NODESK: 2, STEP: 3, SEAT: 4, PARAM: 5, RULE: 6
},
handle: function (rpc, data) {
var errcode = (data && typeof data.errcode === 'number') ? data.errcode : 0;
console.warn('[EQW] 请求失败: rpc=' + rpc + ' errcode=' + errcode);
EventBus.emit(EQW_Events.EQW_RPC_FAILED, { rpc: rpc, errcode: errcode });
}
};