public EndPointListener( IPAddress address, int port, bool secure, string certFolderPath, X509Certificate2 defaultCert ) { if (secure) { _secure = secure; _cert = getCertificate(port, certFolderPath, defaultCert); if (_cert == null) { throw new ArgumentException("Server certificate not found."); } } _endpoint = new IPEndPoint(address, port); _socket = SocketUtilsFactory.Utils.CreateSocket(address); _socket.Bind(_endpoint); _socket.Listen(500); var args = SocketUtilsFactory.Utils.CreateSocketAsyncEventArgs(); args.UserToken = this; args.Completed += onAccept; _socket.AcceptAsync(args); _prefixes = new Dictionary <ListenerPrefix, HttpListener> (); _unregistered = new Dictionary <HttpConnection, HttpConnection> (); }
private async Task AcceptClientAsync() { SocketAwaitable awaitable = Pools.SocketAwaitable.Take(); try { while (!_cts.IsCancellationRequested) { var error = await _listenerSocket.AcceptAsync(awaitable); if (error == SocketError.ConnectionReset) { continue; } if (error == SocketError.OperationAborted) { _log.Error($"{error} returned by AcceptClientAsync - requesting cancellation and shutting down."); _cts.Cancel(); break; } if (error != SocketError.Success) { _log.Error($"AcceptAsync failed with error: {error}"); continue; } var socket = new TcpSocket(awaitable.EventArgs.AcceptSocket); socket.NoDelay = true; // Null it now so we don't dispose of it in the finally clause. awaitable.EventArgs.AcceptSocket = null; var client = _clientFactory(); var ep = socket.RemoteEndPoint; client.SetSocket(socket); _lock.EnterWriteLock(); try { _clients.Add(client); } finally { _lock.ExitWriteLock(); } _log.Debug($"Client from {ep} successfully connected."); } } finally { awaitable.EventArgs.AcceptSocket?.Dispose(); awaitable.EventArgs.AcceptSocket = null; Pools.SocketAwaitable.Return(awaitable); } }
private async Task OpenInternal() { _isOpened = true; _recorder.RecordInfo(nameof(NetworkPoint), $"NetworkPoint opened {(_sListener.LocalEndPoint).Address}:{(_sListener.LocalEndPoint).Port}"); while (_isOpened) { _sListener.Listen(10); ISocket socket = await _sListener.AcceptAsync(); SafeExecution.TryCatch(() => ConnectionAcceptedHandler(socket), ExceptionHandler); } }
private Func <AddressFamily, SocketType, ProtocolType, ISocket> ArrangeSocketFactory(ISocket socketMock = default, bool returnTask = true) { if (socketMock == default) { socketMock = Mock.Create <ISocket>(); } if (returnTask) { var tcs = new TaskCompletionSource <ISocket>(); Mock.Arrange(() => socketMock.AcceptAsync()).Returns(tcs.Task); } var factory = Mock.Create <Func <AddressFamily, SocketType, ProtocolType, ISocket> >(); Mock.Arrange(() => factory.Invoke(default, default, default))
/// <summary> /// Begins an asynchronous read operation that uses these event args. /// </summary> /// <param name="socket">The socket.</param> /// <param name="cancellationToken">A token to monitor for cancellation requests. The default value is <see cref="System.Threading.CancellationToken.None" />.</param> /// <returns> /// A <see cref="Task{ISocket}" /> that represents the asynchronous accept operation. /// </returns> /// <exception cref="System.InvalidOperationException">EventArgs already in use.</exception> public Task <ISocket> AcceptAsync(ISocket socket, CancellationToken cancellationToken = default(CancellationToken)) { var completionSource = new TaskCompletionSource <ISocket>(); if (Interlocked.CompareExchange(ref _completionSource, completionSource, null) != null) { throw new InvalidOperationException(Properties.Resources.InvalidOperation_ObjectInUse); } _cancelled = false; _registration = cancellationToken.Register(Cancel); if (!socket.AcceptAsync(this)) { OnCompleted(this); } return(completionSource.Task); }
public static async Task <SocketError> AcceptAsync(this ISocket socket, SocketAwaitable awaitable) { Requires.NotNull(awaitable, nameof(awaitable)); try { awaitable.Reset(); if (!socket.AcceptAsync(awaitable.EventArgs)) { awaitable.CompleteSynchronously(); } await awaitable; return(awaitable.EventArgs.SocketError); } catch (ObjectDisposedException) { return(SocketError.ConnectionAborted); } }
/// <summary> /// Opens the asynchronous. /// </summary> /// <param name="context">The context.</param> /// <param name="bearerTokenPredicate">The bearer token predicate.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns></returns> /// <exception cref="Exception">Invalid Bearer Token</exception> /// <exception cref="ArgumentOutOfRangeException">method</exception> public async Task OpenAsync(HttpContext context, ILogger logger, Func <string, bool> bearerTokenPredicate = null, CancellationToken?cancellationToken = null) { var correlation = Guid.NewGuid(); var webSockets = context.WebSockets; if (!webSockets.IsWebSocketRequest) { context.Response.StatusCode = 405; return; } context.Response.StatusCode = 101; var ws = await _socket.AcceptAsync(webSockets).ConfigureAwait(false); AutomaClient client = null; try { var bearerToken = await ws.ReceiveAsync <string>(cancellationToken).ConfigureAwait(false); if (!bearerTokenPredicate?.Invoke(bearerToken) ?? true) { throw new Exception("Invalid Bearer Token"); } var opened = true; while (opened && !context.RequestAborted.IsCancellationRequested) { var method = await ws.ReceiveAsync <ProxyMethod>(cancellationToken).ConfigureAwait(false); switch (method) { case ProxyMethod.Open: { var args = await ws.ReceiveObjectAsync <Args>(cancellationToken).ConfigureAwait(false); logger?.LogInformation($"[{correlation}] Open: {((JsonElement)args["_base"]).GetProperty("Type").GetString()}"); client = AutomaClient.Parse(args); break; } case ProxyMethod.Custom: { var registration = await ws.ReceiveAsync <Type>(cancellationToken).ConfigureAwait(false); var param = await ws.ReceiveTypedAsync(cancellationToken).ConfigureAwait(false); var tag = await ws.ReceiveTypedAsync(cancellationToken).ConfigureAwait(false); logger?.LogInformation($"[{correlation}] Custom: {registration?.Name}"); var(obj, custom) = await client.Automa.CustomAsync(registration, param, tag).ConfigureAwait(false); await ws.SendBarrier(false, cancellationToken).ConfigureAwait(false); if (custom is ICustomWithTransfer customWithTransfer) { await customWithTransfer.SendAsync(ws, param).ConfigureAwait(false); await ws.SendBarrier(false, cancellationToken).ConfigureAwait(false); } await ws.SendTypedAsync(obj, cancellationToken).ConfigureAwait(false); break; } case ProxyMethod.Login: { var credential = await ws.ReceiveObjectAsync <NetworkCredential>(cancellationToken).ConfigureAwait(false); client.ServiceLogin = credential.UserName; client.ServicePassword = credential.Password; var tag = await ws.ReceiveTypedAsync(cancellationToken).ConfigureAwait(false); logger?.LogInformation($"[{correlation}] Login: {client.ServiceLogin}"); await client.Automa.LoginAsync(tag).ConfigureAwait(false); break; } case ProxyMethod.SelectApplication: { var application = await ws.ReceiveAsync <string>(cancellationToken).ConfigureAwait(false); var tag = await ws.ReceiveTypedAsync(cancellationToken).ConfigureAwait(false); logger?.LogInformation($"[{correlation}] SelectApplication: {application}"); var obj = await client.Automa.SelectApplicationAsync(application, tag).ConfigureAwait(false); await ws.SendBarrier(false, cancellationToken).ConfigureAwait(false); await ws.SendTypedAsync(obj, cancellationToken).ConfigureAwait(false); break; } case ProxyMethod.SetDeviceAccessToken: { var url = await ws.ReceiveAsync <string>(cancellationToken).ConfigureAwait(false); var code = await ws.ReceiveAsync <string>(cancellationToken).ConfigureAwait(false); var tag = await ws.ReceiveTypedAsync(cancellationToken).ConfigureAwait(false); logger?.LogInformation($"[{correlation}] SetDeviceAccessTokenAsync: {url}, {code}"); await client.Automa.SetDeviceAccessTokenAsync(url, code, tag).ConfigureAwait(false); break; } case ProxyMethod.GetCookies: { logger?.LogInformation($"[{correlation}] GetCookies"); await ws.SendBarrier(false, cancellationToken).ConfigureAwait(false); await ws.SendObjectAsync(client.Automa.Cookies, cancellationToken).ConfigureAwait(false); break; } case ProxyMethod.Dispose: { logger?.LogInformation($"[{correlation}] Dispose"); opened = false; break; } default: throw new ArgumentOutOfRangeException(nameof(method), method.ToString()); } await ws.SendBarrier(true, cancellationToken).ConfigureAwait(false); } } catch (Exception e) { logger?.LogCritical(e, $"{correlation}>Exception"); await ws.SendExceptionAsync(e, cancellationToken); } finally { client?.Dispose(); } logger?.LogInformation($"[{correlation}] Done"); }