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); } }
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); }