private async Task DispatchFaultAsync(
            IConnection connection,
            Message request,
            Fault fault,
            CancellationToken cancellationToken)
        {
            Message message;

            var jsonPayload = JsonSerializationUtilities.FromObject(fault);

            if (request == null)
            {
                var requestId = _idGenerator.GenerateUniqueId();

                message = new Message(requestId, MessageType.Fault, MessageMethod.None, jsonPayload);

                await connection.SendAsync(message, cancellationToken);
            }
            else
            {
                message = new Message(request.RequestId, MessageType.Fault, request.Method, jsonPayload);

                await DispatchWithExistingContextAsync(connection, message, cancellationToken);
            }
        }
Exemple #2
0
        /// <summary>
        /// Asynchronously starts processing a fault response for the inbound request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="exception">An exception.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="request" />
        /// is either <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="exception" />
        /// is <c>null</c>.</exception>
        public void BeginFaultAsync(Message request, Exception exception)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (exception == null)
            {
                throw new ArgumentNullException(nameof(exception));
            }

            var responsePayload = new Fault(exception.Message);
            var response        = new Message(
                request.RequestId,
                MessageType.Fault,
                request.Method,
                JsonSerializationUtilities.FromObject(responsePayload));

            Task.Run(async() =>
            {
                // Top-level exception handler for a worker pool thread.
                try
                {
                    await _connection.SendAsync(response, _cancellationToken).ConfigureAwait(false);
                }
                catch (Exception)
                {
                }
            },
                     _cancellationToken);
        }
        private void Receive(object state)
        {
            Message message = null;

            try
            {
                var cancellationToken = (CancellationToken)state;

                string line;

                // Reading from the standard input stream is a blocking call; while we're
                // in a read call we can't respond to cancellation requests.
                while (!IsClosed && (line = _reader.ReadLine()) != null)
                {
                    message = null;

                    cancellationToken.ThrowIfCancellationRequested();

                    message = JsonSerializationUtilities.Deserialize <Message>(line);

                    if (message != null)
                    {
                        FireMessageReceivedEvent(message);
                    }
                }
            }
            catch (Exception ex)
            {
                FireFaultEvent(ex, message);
            }
        }
        /// <summary>
        /// Deserializes a message payload.
        /// </summary>
        /// <typeparam name="TPayload">The message payload type.</typeparam>
        /// <param name="message">The message.</param>
        /// <returns>The deserialized message payload of type <typeparamref name="TPayload" />
        /// or <c>null</c> if no payload exists.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="message" /> is <c>null</c>.</exception>
        public static TPayload DeserializePayload <TPayload>(Message message)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            if (message.Payload == null)
            {
                return(default(TPayload));
            }

            return(JsonSerializationUtilities.ToObject <TPayload>(message.Payload));
        }
        /// <summary>
        /// Asynchronously starts processing a fault response for the inbound request.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <param name="exception">An exception.</param>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="request" />
        /// is either <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="exception" />
        /// is <c>null</c>.</exception>
        public void BeginFaultAsync(Message request, Exception exception)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (exception == null)
            {
                throw new ArgumentNullException(nameof(exception));
            }

            var responsePayload = new Fault(exception.Message);
            var response        = new Message(
                request.RequestId,
                MessageType.Fault,
                request.Method,
                JsonSerializationUtilities.FromObject(responsePayload));

            if (_logger.IsEnabled)
            {
                _logger.Write(new TaskLogMessage(_logger.Now, response.RequestId, response.Method, response.Type, TaskState.Queued));
            }

            Task.Run(async() =>
            {
                // Top-level exception handler for a worker pool thread.
                try
                {
                    if (_logger.IsEnabled)
                    {
                        _logger.Write(new TaskLogMessage(_logger.Now, response.RequestId, response.Method, response.Type, TaskState.Executing));
                    }

                    await _connection.SendAsync(response, _cancellationToken);
                }
                catch (Exception)
                {
                }
                finally
                {
                    if (_logger.IsEnabled)
                    {
                        _logger.Write(new TaskLogMessage(_logger.Now, response.RequestId, response.Method, response.Type, TaskState.Completed));
                    }
                }
            },
                     _cancellationToken);
        }
        /// <summary>
        /// Instantiates a new <see cref="Message" /> class.
        /// </summary>
        /// <typeparam name="TPayload">The message payload type.</typeparam>
        /// <param name="requestId">The message request ID.</param>
        /// <param name="type">The message type.</param>
        /// <param name="method">The message method.</param>
        /// <param name="payload">The message payload.</param>
        /// <returns>a <see cref="Message" /> instance.</returns>
        /// <exception cref="ArgumentException">Thrown if <paramref name="requestId" />
        /// is either <c>null</c> or an empty string.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="payload" /> is <c>null</c>.</exception>
        public static Message Create <TPayload>(
            string requestId,
            MessageType type,
            MessageMethod method,
            TPayload payload)
            where TPayload : class
        {
            if (string.IsNullOrEmpty(requestId))
            {
                throw new ArgumentException(Strings.ArgumentCannotBeNullOrEmpty, nameof(requestId));
            }

            if (payload == null)
            {
                throw new ArgumentNullException(nameof(payload));
            }

            var jsonPayload = JsonSerializationUtilities.FromObject(payload);

            return(new Message(requestId, type, method, jsonPayload));
        }
        private void OnLineRead(object sender, LineReadEventArgs e)
        {
            Message message = null;

            // Top-level exception handler for a worker pool thread.
            try
            {
                if (!IsClosed && !string.IsNullOrEmpty(e.Line))
                {
                    message = JsonSerializationUtilities.Deserialize <Message>(e.Line);

                    if (message != null)
                    {
                        FireMessageReceivedEvent(message);
                    }
                }
            }
            catch (Exception ex)
            {
                FireFaultEvent(ex, message);
            }
        }
Exemple #8
0
        /// <summary>
        /// Asynchronously sends a message to the target.
        /// </summary>
        /// <param name="message">The message to send.</param>
        /// <param name="cancellationToken">A cancellation token.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        /// <exception cref="ObjectDisposedException">Thrown if this object is disposed.</exception>
        /// <exception cref="InvalidOperationException">Thrown if <see cref="Connect" /> has not been called.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="message" /> is <c>null</c>.</exception>
        /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken" />
        /// is cancelled.</exception>
        public Task SendAsync(Message message, CancellationToken cancellationToken)
        {
            ThrowIfDisposed();

            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            cancellationToken.ThrowIfCancellationRequested();

            if (!_hasConnected)
            {
                throw new InvalidOperationException(Strings.Plugin_NotConnected);
            }

            if (!_isClosed)
            {
                lock (_sendLock)
                {
                    using (var jsonWriter = new JsonTextWriter(_textWriter))
                    {
                        jsonWriter.CloseOutput = false;

                        JsonSerializationUtilities.Serialize(jsonWriter, message);

                        // We need to terminate JSON objects with a delimiter (i.e.:  a single
                        // newline sequence) to signal to the receiver when to stop reading.
                        _textWriter.WriteLine();
                        _textWriter.Flush();
                    }
                }
            }

            return(Task.FromResult(0));
        }