public bool Remove(IServerSession session)
        {
            if (session == null)
            {
                return(false);
            }

            bool exist = false;

            lock (_sessions)
            {
                var unicastAddress = session.UnicastAddress;
                exist = _sessions.RemoveValue(unicastAddress, session);
                if (exist)
                {
                    LeaveAll(session);
                }
            }

            if (exist)
            {
                session.Close();
                ServerEvents.AsyncRaiseClientDisconnectedEvent(_server, session);
            }

            return(exist);
        }
        /// <summary>
        /// 运行
        /// </summary>
        public async Task Run()
        {
            if (_running)
            {
                return;
            }
            _running = true;

            _bossGroup   = new MultithreadEventLoopGroup(1);
            _workerGroup = new MultithreadEventLoopGroup();

            X509Certificate2 tlsCertificate = null;

            if (this.Config.IsSsl)
            {
                tlsCertificate = new X509Certificate2(Path.Combine(AppContext.ProcessDirectory, "anycast.pfx"), "password");
            }

            var bootstrap = new ServerBootstrap();

            bootstrap
            .Group(_bossGroup, _workerGroup)
            .Channel <TcpServerSocketChannel>()
            .Option(ChannelOption.SoBacklog, 1024)
            .ChildOption <bool>(ChannelOption.SoKeepalive, true)
            .Handler(new LoggingHandler("AS-LSTN"))
            .ChildHandler(new ActionChannelInitializer <IChannel>(channel =>
            {
                channel.Configuration.Allocator = UnpooledByteBufferAllocator.Default;     //由于PooledByteBuffer有内存不释放,所以我们使用 非池的字节缓冲区

                IChannelPipeline pipeline = channel.Pipeline;
                if (tlsCertificate != null)
                {
                    pipeline.AddLast("tls", TlsHandler.Server(tlsCertificate));
                }
                pipeline.AddLast("framing-enc", new MessageEncoder());
                pipeline.AddLast("framing-dec", new MessageDecoder());

                pipeline.AddLast("ReadTimeout", new ReadTimeoutHandler(Settings.Timeout));     //超过指定时间没有接收到客户端任何信息,自动关闭对应的客户端通道
                pipeline.AddLast("LoginAuthResp", new LoginAuthRespHandler(this));
                pipeline.AddLast("HeartBeatResp", new HeartBeatRespHandler(this));
                pipeline.AddLast("ServerLogic", new ServerLogicHandler(this));
            }));

            try
            {
                _boundChannel = await bootstrap.BindAsync(this.Config.Port);

                ServerEvents.AsyncRaiseRunning(this, this);
            }
            catch (Exception ex)
            {
                _running = false;
                ServerEvents.AsyncRaiseError(this, new RunServerException(ex));
            }
        }
        public void Add(IServerSession session)
        {
            lock (_sessions)
            {
                var unicastAddress = session.UnicastAddress;
                _sessions.Add(unicastAddress, session);
            }

            ServerEvents.AsyncRaiseClientConnected(_server, session);
        }
 protected void SafeProcess(Action action, IChannelHandlerContext context)
 {
     try
     {
         action();
     }
     catch (Exception ex)
     {
         Offline(context);
         ServerEvents.AsyncRaiseError(this.Server, ex);
     }
 }
Example #5
0
        public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
        {
            SafeProcess(() =>
            {
                Offline(context);

                if (Util.OfflineHandle(context, exception))
                {
                    return;
                }

                ServerEvents.AsyncRaiseError(this.Server, exception);
                context.FireExceptionCaught(exception);
            }, context);
        }
 public override void ChannelRead(IChannelHandlerContext context, object message)
 {
     SafeProcess(() =>
     {
         var msg = (Message)message;
         if (msg.Type == MessageType.HeartBeatRequest)
         {
             //响应心跳请求
             context.WriteAndFlushAsync(_heartBeatMsg);
             ServerEvents.AsyncRaiseHeartBeatReceived(this.Server, this.Sessions.GetSession(context.Channel));
         }
         else
         {
             context.FireChannelRead(msg);
         }
     }, context);
 }