public void OnAccept(xx.UvTcpPeer peer) { Console.WriteLine("client peer [" + peer.ip + "] accepted."); peer.OnReceiveRequest = (serial, bbRecv) => { // 试着解码. 失败直接断开 var recv = bbRecv.TryReadRoot<xx.IObject>(); if (recv == null) { peer.Dispose(); return; } Console.WriteLine("client peer " + peer.ip + " recv: " + recv); // 分发到处理函数 switch (recv) { case PKG.Client_Login.Auth a: Handle_Auth(serial, a, peer); break; default: peer.Dispose(); return; } }; }
public void Handle_Login_Auth(uint serial, PKG.Login_DB.Auth a, xx.UvTcpPeer peer) { // 参数合法性初步检查 if (string.IsNullOrEmpty(a.username) || a.password == null) { peer.Send(new PKG.Generic.Error { number = -2, text = "username is null/empty or password is null." }); } // 模拟数据库异步查询 new Task(() => { // 准备回发结果 xx.IObject pkg = null; try { // 模拟一个耗时 SQL 操作 Thread.Sleep(1000); if (a.username == "abc" && a.password == "123") { pkg = new PKG.DB_Login.Auth_Success { userId = 12 }; } else { pkg = new PKG.Generic.Error { number = -3, text = "bad username or password." }; } } catch (Exception ex) { pkg = new PKG.Generic.Error { number = -4, text = ex.Message }; } // 核实回发结果是否已经填充 Debug.Assert(pkg != null); // 封送到 uv 主线程去执行 dispatcher.Dispatch(() => { // 检查连接的死活. 如果没断开就回发结果 if (peer.alive) { // 发送处理结果 peer.SendResponse(serial, pkg); } }); }).Start(); }
public void SetLoginPeer(xx.UvTcpPeer peer) { if (loginPeer != null && loginPeer.alive) { loginPeer.Send(new PKG.Generic.Error { number = -1, text = "another login server connected." }); loginPeer.DelayRelease(1); } loginPeer = peer; loginPeer.OnReceivePackage = null; loginPeer.OnReceiveRequest = (serial, bb) => { // 试着解包 var pkg = bb.TryReadRoot <xx.IObject>(); // 如果解包失败, 立即踢掉 并 清掉 if (pkg == null) { loginPeer.Dispose(); loginPeer = null; return; } Console.WriteLine("recv server_login package: " + pkg); // 根据请求来分发到处理函数 switch (pkg) { case PKG.Login_DB.Auth a: Handle_Login_Auth(serial, a, peer); break; default: Console.WriteLine("unhandled pkg: ", pkg); break; } }; Console.WriteLine("server_login connected."); }
public void OnAccept(xx.UvTcpPeer peer) { // 首次建立连接时, 身份不明, 先 bind 身份检测函数 peer.OnReceivePackage = (bb) => { // 试着解包 var pkg = bb.TryReadRoot <xx.IObject>(); // 如果解包失败, 立即踢掉 if (pkg == null) { peer.Dispose(); return; } // 对于匿名连接, 先进行 ServiceInfo 检测. 如果收到其他类型的包, 直接踢掉 int r = 0; switch (pkg) { case PKG.Generic.ServerInfo si: r = HandleServerInfo(si, peer); break; default: r = -1; break; } // 判断处理结果 if (r == 0) // 正确执行, 保持连接 { } else if (r < 0) // 处理失败 { peer.Dispose(); // 直接断开 } else // r > 0 { peer.DelayRelease(r); // 延迟断开 } }; }
public int HandleServerInfo(PKG.Generic.ServerInfo si, xx.UvTcpPeer peer) { switch (si.name) { case "login": SetLoginPeer(peer); break; case "lobby": //SetLobbyPeer(peer); break; case "game1": //SetGame1Peer(peer); break; default: return(-1); } return(0); }
public void Handle_Auth(uint serial, PKG.Client_Login.Auth a, xx.UvTcpPeer peer) { // 如果还没有连上 if (!dbClient.alive) { peer.SendResponse(serial, new PKG.Generic.Error { number = -1, text = "dbClient disconnected." }); return; } // 向 db 服务发起问询 dbClient.SendRequestEx(new PKG.Login_DB.Auth { username = a.username, password = a.password }, recv => { // 如果等到 db 返回结果到达时 peer 已经断开, 则后续都不用继续做了 if (!peer.alive) return; // rpc 超时 if (recv == null) { peer.SendResponse(serial, new PKG.Generic.Error { number = -2, text = "dbClient Auth timeout." }); } else { switch (recv) { case PKG.Generic.Error o: peer.SendResponse(serial, o); break; case PKG.DB_Login.Auth_Success o: // todo: 通过 lobbyClient 继续 SendRequestEx( PKG.Login_Lobby.Enter ). 在收到 Lobby 返回的 EnterSuccess 之后 通过 peer 发送 lobby 生成的 token peer.SendResponse(serial, new PKG.Generic.Success { }); break; default: peer.SendResponse(serial, new PKG.Generic.Error { number = -3, text = "dbClient Auth Result: unhandled package " + recv.ToString() }); break; } } }); }