public void NotifySessionQuit(TcpSession s) { PurifyConsumer.Push(s); }
private static async Task onCron(UInt16 id, TcpSession session, byte[] buffer) { String buf = System.Text.Encoding.Default.GetString(buffer); await session.send(buf, id); }
public void Start() { var Success = false; try { IsRunningValue.Update ( b => { if (b) { throw new InvalidOperationException(); } if (BindingsValue.Length == 0) { throw new Exception("NoValidBinding"); } ListeningTaskTokenSource = new CancellationTokenSource(); var ListeningTaskToken = ListeningTaskTokenSource.Token; Action <TcpSession> Purify = StoppingSession => { SessionSets.DoAction ( ss => { if (ss.Sessions.Contains(StoppingSession)) { ss.Sessions.Remove(StoppingSession); var IpAddress = StoppingSession.RemoteEndPoint.Address; var isi = ss.IpSessions[IpAddress]; if (isi.Authenticated.Contains(StoppingSession)) { isi.Authenticated.Remove(StoppingSession); } isi.Count -= 1; if (isi.Count == 0) { ss.IpSessions.Remove(IpAddress); } } } ); StoppingSession.Dispose(); }; Action <Socket> Accept = a => { IPEndPoint ep; try { ep = (IPEndPoint)(a.RemoteEndPoint); } catch { a.Dispose(); return; } var s = new TcpSession(this, new StreamedAsyncSocket(a, UnauthenticatedSessionIdleTimeoutValue, QueueUserWorkItem), ep, VirtualTransportServerFactory, QueueUserWorkItem); if (MaxConnectionsValue.HasValue && (SessionSets.Check(ss => ss.Sessions.Count) >= MaxConnectionsValue.Value)) { PurifyConsumer.DoOne(); } if (MaxConnectionsValue.HasValue && (SessionSets.Check(ss => ss.Sessions.Count) >= MaxConnectionsValue.Value)) { try { s.Start(); OnMaxConnectionsExceeded(s); } finally { s.Dispose(); } return; } if (MaxConnectionsPerIPValue.HasValue && (SessionSets.Check(ss => ss.IpSessions.ContainsKey(ep.Address) ? ss.IpSessions[ep.Address].Count : 0) >= MaxConnectionsPerIPValue.Value)) { try { s.Start(); OnMaxConnectionsPerIPExceeded(s); } finally { PurifyConsumer.Push(s); } return; } if (MaxUnauthenticatedPerIPValue.HasValue && (SessionSets.Check(ss => ss.IpSessions.ContainsKey(ep.Address) ? ss.IpSessions[ep.Address].Count : 0) >= MaxUnauthenticatedPerIPValue.Value)) { try { s.Start(); OnMaxConnectionsPerIPExceeded(s); } finally { PurifyConsumer.Push(s); } return; } SessionSets.DoAction ( ss => { ss.Sessions.Add(s); if (ss.IpSessions.ContainsKey(ep.Address)) { ss.IpSessions[ep.Address].Count += 1; } else { var isi = new IpSessionInfo(); isi.Count += 1; ss.IpSessions.Add(ep.Address, isi); } } ); s.Start(); }; AcceptConsumer = new AsyncConsumer <Socket>(QueueUserWorkItem, a => { Accept(a); return(true); }, int.MaxValue); var Exceptions = new List <Exception>(); foreach (var Binding in BindingsValue) { Func <Socket> CreateSocket = () => { var s = new Socket(Binding.AddressFamily, SocketType.Stream, ProtocolType.Tcp); return(s); }; var Socket = CreateSocket(); try { Socket.Bind(Binding); } catch (SocketException ex) { Exceptions.Add(ex); continue; } Socket.Listen(MaxConnectionsValue.HasValue ? (MaxConnectionsValue.Value + 1) : 128); var BindingInfo = new BindingInfo(); BindingInfo.EndPoint = Binding; BindingInfo.Socket = new LockedVariable <Socket>(Socket); Func <SocketAsyncEventArgs, Boolean> Completed = args => { try { if (ListeningTaskToken.IsCancellationRequested) { return(false); } if (args.SocketError == SocketError.Success) { var a = args.AcceptSocket; AcceptConsumer.Push(a); } else { BindingInfo.Socket.Update ( OriginalSocket => { try { OriginalSocket.Dispose(); } catch (Exception) { } var NewSocket = CreateSocket(); NewSocket.Bind(Binding); NewSocket.Listen(MaxConnectionsValue.HasValue ? (MaxConnectionsValue.Value + 1) : 128); return(NewSocket); } ); } } finally { args.Dispose(); } BindingInfo.Start(); return(true); }; BindingInfo.ListenConsumer = new AsyncConsumer <SocketAsyncEventArgs>(QueueUserWorkItem, Completed, 1); BindingInfo.Start = () => { var EventArgs = new SocketAsyncEventArgs(); var bs = BindingInfo.Socket.Check(s => s); EventArgs.Completed += (o, args) => { if (ListeningTaskToken.IsCancellationRequested) { return; } BindingInfo.ListenConsumer.Push(args); }; try { if (!bs.AcceptAsync(EventArgs)) { BindingInfo.ListenConsumer.Push(EventArgs); } } catch (ObjectDisposedException) { } }; BindingInfos.Add(BindingInfo); } if (BindingInfos.Count == 0) { throw new AggregateException(Exceptions); } PurifyConsumer = new AsyncConsumer <TcpSession>(PurifierQueueUserWorkItem, s => { Purify(s); return(true); }, int.MaxValue); foreach (var BindingInfo in BindingInfos) { BindingInfo.Start(); } Success = true; return(true); } ); } finally { if (!Success) { Stop(); } } }
private static void connectCallback(TcpSession session) { System.Console.WriteLine("connect close : {0}", session.ID); }