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); } }
/// <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); } }
/// <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)); }