예제 #1
0
        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();
            }
        }
예제 #2
0
        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();
            }
        }
예제 #3
0
        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();
            }
        }