static async Task ConsumeAsync(IServerChannel serverChannel, CancellationToken cancellationToken) { try { await serverChannel.EstablishSessionAsync( serverChannel.Transport.GetSupportedCompression(), serverChannel.Transport.GetSupportedEncryption(), new[] { AuthenticationScheme.Guest }, (identity, authentication) => new AuthenticationResult(null, new Node() { Name = EnvelopeId.NewId(), Domain = "limeprotocol.org", Instance = Environment.MachineName }).AsCompletedTask(), cancellationToken); if (serverChannel.State == SessionState.Established) { _nodeChannelsDictionary.Add(serverChannel.RemoteNode, serverChannel); // Consume the channel envelopes var consumeMessagesTask = ConsumeMessagesAsync(serverChannel, cancellationToken).WithPassiveCancellation(); var consumeCommandsTask = ConsumeCommandsAsync(serverChannel, cancellationToken).WithPassiveCancellation(); var consumeNotificationsTask = ConsumeNotificationsAsync(serverChannel, cancellationToken).WithPassiveCancellation(); // Awaits for the finishing envelope var finishingSessionTask = serverChannel.ReceiveFinishingSessionAsync(cancellationToken); // Stops the consumer when any of the tasks finishes await Task.WhenAny(finishingSessionTask, consumeMessagesTask, consumeCommandsTask, consumeNotificationsTask); if (finishingSessionTask.IsCompleted) { await serverChannel.SendFinishedSessionAsync(CancellationToken.None); } } if (serverChannel.State != SessionState.Finished && serverChannel.State != SessionState.Failed) { await serverChannel.SendFailedSessionAsync(new Reason() { Code = ReasonCodes.SESSION_ERROR, Description = "The session failed" }, CancellationToken.None); } } catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested) { } finally { if (serverChannel.RemoteNode != null) { _nodeChannelsDictionary.Remove(serverChannel.RemoteNode); } serverChannel.DisposeIfDisposable(); } }
private async Task ConsumeAsync(IServerChannel serverChannel) { try { // Establishes the session await serverChannel.EstablishSessionAsync( serverChannel.Transport.GetSupportedCompression().Intersect(_enabledCompressionOptions) .ToArray(), serverChannel.Transport.GetSupportedEncryption().Intersect(_enabledEncryptionOptions).ToArray(), _schemeOptions, _authenticator, _nodeRegistry.TryRegisterAsync, _listenerCts.Token) .ConfigureAwait(false); if (serverChannel.State == SessionState.Established) { await ListenAsync(serverChannel); } // If something bizarre occurs if (serverChannel.IsActive()) { await serverChannel.SendFailedSessionAsync( new Reason() { Code = ReasonCodes.SESSION_ERROR, Description = "The session was terminated by the server" }, _listenerCts.Token); } } catch (OperationCanceledException) when(_listenerCts.IsCancellationRequested) { if (serverChannel.IsActive()) { await serverChannel.SendFailedSessionAsync( new Reason() { Code = ReasonCodes.SESSION_ERROR, Description = "The server is being shut down" }, CancellationToken.None); } } catch (Exception ex) { if (_exceptionHandler != null) { await _exceptionHandler(ex).ConfigureAwait(false); } if (serverChannel.IsActive()) { await serverChannel.SendFailedSessionAsync( new Reason() { Code = ReasonCodes.SESSION_ERROR, Description = "An unexpected server error occurred" }, CancellationToken.None); } } finally { serverChannel.DisposeIfDisposable(); } }
private async Task ConsumeAsync(IServerChannel serverChannel) { try { // Establishes the session await serverChannel.EstablishSessionAsync( serverChannel.Transport.GetSupportedCompression().Intersect(_enabledCompressionOptions) .ToArray(), serverChannel.Transport.GetSupportedEncryption().Intersect(_enabledEncryptionOptions).ToArray(), _schemeOptions, _authenticator, _listenerCts.Token) .ConfigureAwait(false); if (serverChannel.State == SessionState.Established) { if (!_nodeChannelsDictionary.TryAdd(serverChannel.RemoteNode, serverChannel)) { await serverChannel.SendFailedSessionAsync(new Reason() { Code = ReasonCodes.SESSION_ERROR, Description = "Could not register the channel node" }, _listenerCts.Token); return; } // Initializes a new consumer var channelListener = _channelListenerFactory(); try { // Consume the channel envelopes channelListener.Start(serverChannel); // Awaits for the finishing envelope var finishingSessionTask = serverChannel.ReceiveFinishingSessionAsync(_listenerCts.Token); // Stops the consumer when any of the tasks finishes await Task.WhenAny( finishingSessionTask, channelListener.MessageListenerTask, channelListener.CommandListenerTask, channelListener.NotificationListenerTask); if (finishingSessionTask.IsCompleted) { await serverChannel.SendFinishedSessionAsync(_listenerCts.Token); } } finally { channelListener.Stop(); if (serverChannel.RemoteNode != null) { _nodeChannelsDictionary.TryRemove(serverChannel.RemoteNode, out _); } } } // If something bizarre occurs if (serverChannel.State != SessionState.Finished && serverChannel.State != SessionState.Failed) { await serverChannel.SendFailedSessionAsync(new Reason() { Code = ReasonCodes.SESSION_ERROR, Description = "The session failed" }, _listenerCts.Token); } } catch (OperationCanceledException) when(_listenerCts.IsCancellationRequested) { await serverChannel.SendFailedSessionAsync(new Reason() { Code = ReasonCodes.SESSION_ERROR, Description = "The server is being shut down" }, CancellationToken.None); } catch (Exception ex) { if (_exceptionHandler != null) { await _exceptionHandler(ex).ConfigureAwait(false); } } finally { serverChannel.DisposeIfDisposable(); } }