void Start()
        {
            //初始化服务器
            server = new Server(port);

            //开启TLS加密,这是可选的,可用不设置
            TextAsset        textAsset = Resources.Load <TextAsset>("vovgou.pfx");
            X509Certificate2 cert      = new X509Certificate2(textAsset.bytes, "123456");

            server.Secure(true, cert, (sender, certificate, chain, sslPolicyErrors) =>
            {
                //服务器设置不要求客户端证书,服务器方不校验客户端的协议,直接返回true
                return(true);
            });

            //----------------------

            //创建TcpChannel,如果游戏协议没有定义握手消息,那么HandshakeHandler可以为null
            var channel = new TcpChannel(new DefaultDecoder(), new DefaultEncoder(), new HandshakeHandler());

            channel.NoDelay     = true;
            channel.IsBigEndian = true;//默认使用大端字节序,一般网络字节流用大端

            //如果服务器没有开启TLS加密,可用不设置
            channel.Secure(true, "vovgou.com", null, (sender, certificate, chain, sslPolicyErrors) =>
            {
                //客户端方校验服务器端的自签名协议
                if (sslPolicyErrors == SslPolicyErrors.None)
                {
                    return(true);
                }

                if (certificate != null && certificate.GetCertHashString() == "3C33D870E7826E9E83B4476D6A6122E497A6D282")
                {
                    return(true);
                }

                return(false);
            });

            //每个20秒空闲则触发空闲事件,并且每隔20秒触发一次,时间为0则关闭空闲事件,首次空闲First为true。示例中只开启了读写都空闲的事件
            IdleStateMonitor idleStateMonitor = new IdleStateMonitor(TimeSpan.FromTicks(0), TimeSpan.FromTicks(0), TimeSpan.FromSeconds(20f));

            connector = new DefaultConnector <Request, Response, Notification>(channel, idleStateMonitor);
            connector.AutoReconnect = true;//开启自动重连,只重连一次,失败后不再重试,建议使用心跳包保证连接可用

            //订阅事件,收到ConnectionEventArgs参数
            eventSubscription = connector.Events().Filter(e =>
            {
                //消息过滤,只订阅ConnectionEventArgs类型的事件
                //if (e is ConnectionEventArgs)
                //    return true;
                //return false;
                return(true);
            }).ObserveOn(SynchronizationContext.Current).Subscribe((e) =>
            {
                Debug.LogFormat("Client Received Event:{0}", e);
            });

            //订阅通知
            //使用ObserveOn(SynchronizationContext.Current)切换消息处理线程为当前的UI线程
            messageSubscription = connector.Received().Filter(notification =>
            {
                //过滤消息,只监听CommandID在0-100之间的消息
                if (notification.CommandID > 0 && notification.CommandID <= 100)
                {
                    return(true);
                }
                return(false);
            }).ObserveOn(SynchronizationContext.Current).Subscribe(notification =>
            {
                Debug.LogFormat("Client Received Notification:{0}", notification);
            });
        }
Example #2
0
        void Start()
        {
            //初始化服务器
            server = new Server(port);

            //开启TLS加密,这是可选的,可用不设置
            TextAsset        textAsset = Resources.Load <TextAsset>("vovgou.pfx");
            X509Certificate2 cert      = new X509Certificate2(textAsset.bytes, "123456");

            server.Secure(true, cert, (sender, certificate, chain, sslPolicyErrors) =>
            {
                //服务器设置不要求客户端证书,服务器方不校验客户端的协议,直接返回true
                return(true);
            });

            //----------------------

            //创建TcpChannel,TcpChannel中不要在插入HandshakeHandler,已经移到DefaultConnector类中
            //如果使用Kcp协议,此处替换为KcpChannel,针对Kcp的支持在Loxodon.Framework.Connection.KCP包中
            //var channel = new KcpChannel(new KcpSetting(), new CodecFactory());
            var channel = new TcpChannel(new DefaultDecoder(), new DefaultEncoder());

            channel.NoDelay     = true;
            channel.IsBigEndian = true;//默认使用大端字节序,一般网络字节流用大端

            //如果服务器没有开启TLS加密,可用不设置
            channel.Secure(true, "vovgou.com", null, (sender, certificate, chain, sslPolicyErrors) =>
            {
                //客户端方校验服务器端的自签名协议
                if (sslPolicyErrors == SslPolicyErrors.None)
                {
                    return(true);
                }

                if (certificate != null && certificate.GetCertHashString() == "3C33D870E7826E9E83B4476D6A6122E497A6D282")
                {
                    return(true);
                }

                return(false);
            });

            //HandshakeHandler 不要放在Channel中,请放入Connector中,这样更合理
            IHandshakeHandler handshakeHandler = new HandshakeHandler();

            //每个20秒空闲则触发空闲事件,并且每隔20秒触发一次,时间为0则关闭空闲事件,首次空闲First为true。示例中只开启了读写都空闲的事件
            IdleStateMonitor idleStateMonitor = new IdleStateMonitor(TimeSpan.FromSeconds(20), TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(20f));

            connector = new DefaultConnector <Request, Response, Notification>(channel, idleStateMonitor, handshakeHandler);
            connector.AutoReconnect = true;//开启自动重连,只重连一次,失败后不再重试,建议使用心跳包保证连接可用

            //订阅事件,收到ConnectionEventArgs参数
            eventSubscription = connector.Events().Filter(e =>
            {
                //消息过滤,只订阅ConnectionEventArgs类型的事件
                //if (e is ConnectionEventArgs)
                //    return true;
                //return false;
                return(true);
            }).ObserveOn(SynchronizationContext.Current).Subscribe((e) =>
            {
                Debug.LogFormat("Client Received Event:{0}", e);
            });

            //订阅通知
            //使用ObserveOn(SynchronizationContext.Current)切换消息处理线程为当前的UI线程
            messageSubscription = connector.Received().Filter(notification =>
            {
                //过滤消息,只监听CommandID在0-100之间的消息
                if (notification.CommandID > 0 && notification.CommandID <= 100)
                {
                    return(true);
                }
                return(false);
            }).ObserveOn(SynchronizationContext.Current).Subscribe(notification =>
            {
                Debug.LogFormat("Client Received Notification:{0}", notification);
            });

            //订阅连接空闲事件,发生心跳消息
            idleEventSubscription = connector.Events()
                                    .Filter(e => e is IdleStateEventArgs)
                                    .ObserveOn(SynchronizationContext.Current)
                                    .Subscribe(e =>
            {
                try
                {
                    if (e is IdleStateEventArgs idleStateEventArgs)
                    {
                        if (idleStateEventArgs.IsFirst && (idleStateEventArgs.State == IdleState.ReaderIdle))
                        {
                            //send a ping message
                            SendHeartbeatMessage();
                        }
                    }
                }
                catch (Exception) { }
            });
        }