/// <summary> /// A callback that gets invoked after we disconnect from the IPEndpoint. /// </summary> /// <param name="result"></param> private void DisconnectCallback(IAsyncResult result) { Promise <ISockNetChannel> promise = (Promise <ISockNetChannel>)result.AsyncState; try { Socket.EndDisconnect(result); if (TryFlaggingAs(ClientSockNetChannelState.Disconnected, ClientSockNetChannelState.Disconnecting)) { SockNetLogger.Log(SockNetLogger.LogLevel.INFO, this, "Disconnected from [{0}]", RemoteEndpoint); stream.Close(); Pipe.HandleClosed(); promise.CreateFulfiller().Fulfill(this); } else { promise.CreateFulfiller().Fulfill(new Exception("Unable to mark channel as disconnected. State was: " + State)); } } catch (Exception e) { promise.CreateFulfiller().Fulfill(e); } }
/// <summary> /// Drains chunks to the given stream and notifies the given promise when it's done. /// </summary> /// <param name="stream"></param> /// <param name="promise"></param> private void DrainToStream(Stream stream, Promise <ChunkedBuffer> promise) { MemoryChunkNode currentChunk = null; lock (_syncRoot) { currentChunk = rootChunk; if (currentChunk == null) { promise.CreateFulfiller().Fulfill(this); return; } rootChunk = rootChunk.next; } stream.BeginWrite(currentChunk.pooledBytes, currentChunk.offset, currentChunk.count, new AsyncCallback(OnDrainToStreamWriteComplete), new DrainChunksState() { currentChunk = currentChunk, stream = stream, promise = promise }); }
/// <summary> /// Binds to the configured endpoint and sets security variables. /// </summary> /// <param name="isSsl"></param> /// <param name="certificateValidationCallback"></param> /// <returns></returns> private Promise <ISockNetChannel> BindInternal(bool isSsl, X509Certificate serverCertificate, RemoteCertificateValidationCallback certificateValidationCallback) { Promise <ISockNetChannel> promise = new Promise <ISockNetChannel>(); if (TryFlaggingAs(ServerSockNetChannelState.Binding, ServerSockNetChannelState.Closed)) { SockNetLogger.Log(SockNetLogger.LogLevel.INFO, this, "Binding to [{0}]...", bindEndpoint); this.IsSsl = isSsl; this.CertificateValidationCallback = certificateValidationCallback; this.ServerCertificate = serverCertificate; Socket.Bind(bindEndpoint); Socket.Listen(backlog); this.State = ServerSockNetChannelState.Bound; SockNetLogger.Log(SockNetLogger.LogLevel.INFO, this, "Bound to [{0}].", LocalEndpoint); Socket.BeginAccept(new AsyncCallback(AcceptCallback), Socket); promise.CreateFulfiller().Fulfill(this); } else { throw new Exception("The server is already bound."); } return(promise); }
/// <summary> /// Disconnects from the IPEndpoint. /// </summary> public Promise <ISockNetChannel> Disconnect() { Promise <ISockNetChannel> promise = new Promise <ISockNetChannel>(); if (TryFlaggingAs(ClientSockNetChannelState.Disconnecting, ClientSockNetChannelState.Connected)) { SockNetLogger.Log(SockNetLogger.LogLevel.INFO, this, "Disconnecting from [{0}]...", RemoteEndpoint); Socket.Shutdown(SocketShutdown.Both); Socket.BeginDisconnect(true, new AsyncCallback(DisconnectCallback), promise); } else { promise.CreateFulfiller().Fulfill(this); } return(promise); }
/// <summary> /// Drains chunks to the given stream and notifies the given promise when it's done. /// </summary> /// <param name="stream"></param> /// <param name="promise"></param> private void DrainToStream(Stream stream, Promise<ChunkedBuffer> promise) { MemoryChunkNode currentChunk = null; lock (_syncRoot) { currentChunk = rootChunk; if (currentChunk == null) { promise.CreateFulfiller().Fulfill(this); return; } rootChunk = rootChunk.next; } stream.BeginWrite(currentChunk.pooledBytes, currentChunk.offset, currentChunk.count, new AsyncCallback(OnDrainToStreamWriteComplete), new DrainChunksState() { currentChunk = currentChunk, stream = stream, promise = promise }); }