Beispiel #1
0
    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;
            }
        };
    }
Beispiel #2
0
    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();
    }
Beispiel #3
0
    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.");
    }
Beispiel #4
0
    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);       // 延迟断开
            }
        };
    }
Beispiel #5
0
    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);
    }
Beispiel #6
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;
                }
            }
        });
    }