/// <summary> /// Begins a communication task with a client socket using the worker instance to perform requested operations. /// </summary> /// <typeparam name="TService">The contract for the service.</typeparam> /// <param name="worker">The TService instance which will fulfill requested operations.</param> /// <param name="clientSocket">The client socket connection.</param> /// <param name="onRequestReceived">(Optional) Action to perform when a client request has been received.</param> /// <param name="onSendingResponse">(Optional) Action to perform once the worker has processed the operation and prior to sending the server response.</param> /// <param name="onError">(Optional) Action to perform when processing encounters an error.</param> /// <returns>Awaitable task hosting the background processing of the client socket connection.</returns> public static void HandleClient <TService>( this TService worker, Socket clientSocket, CancellationToken cancellationToken = default, Action <string, byte[][]> onRequestReceived = null, Action <string, byte[]> onSendingResponse = null, Action <Exception> onError = null) { try { // Continue reading as long as client requests are available. OperationWrapper request; while (!cancellationToken.IsCancellationRequested && clientSocket.Connected && (request = clientSocket.GetWrapperResponse()) != OperationWrapper.SessionEnded) { onRequestReceived?.Invoke(request.Operation, request.Arguments); object result = worker.InvokeRequest(request); // Now send back a response. var response = OperationWrapper.FromResult(request.Operation, result); onSendingResponse?.Invoke(request.Operation, response.Result); clientSocket.SendWrapperRequest(response); } } catch (Exception ex) { if (onError == null) { throw; } onError(ex); } }
/// <summary> /// Begins a communication task with a TPC client using the worker instance to perform requested operations. /// </summary> /// <typeparam name="TService">The contract for the service.</typeparam> /// <param name="worker">The TService instance which will fulfill requested operations.</param> /// <param name="client">The TCP client connection.</param> /// <param name="onRequestReceived">(Optional) Action to perform when a client request has been received.</param> /// <param name="onSendingResponse">(Optional) Action to perform once the worker has processed the operation and prior to sending the server response.</param> /// <param name="onError">(Optional) Action to perform when processing encounters an error.</param> /// <returns>Awaitable task hosting the background processing of the client socket connection.</returns> public static async Task HandleClientAsync <TService>( this TService worker, TcpClient client, CancellationToken cancellationToken = default, Func <string, byte[][], Task> onRequestReceived = null, Func <string, byte[], Task> onSendingResponse = null, Func <Exception, Task> onError = null) { await Task.Run(async() => { try { await using NetworkStream stream = client.GetStream(); // Continue reading as long as client requests are available. OperationWrapper request; while (!cancellationToken.IsCancellationRequested && client.Connected && stream.CanRead && (request = await stream.GetWrapperResponseAsync(cancellationToken, client.ReceiveBufferSize).ConfigureAwait(false)) != OperationWrapper.SessionEnded) { if (onRequestReceived != null) { await onRequestReceived.Invoke(request.Operation, request.Arguments).ConfigureAwait(false); } object result = await worker.InvokeRequestAsync(request).ConfigureAwait(false); // Now send back a response. var response = OperationWrapper.FromResult(request.Operation, result); if (onSendingResponse != null) { await onSendingResponse.Invoke(request.Operation, response.Result).ConfigureAwait(false); } await stream.SendWrapperRequestAsync(response, cancellationToken).ConfigureAwait(false); await stream.FlushAsync().ConfigureAwait(false); } } catch (Exception ex) { if (onError == null) { throw; } await onError.Invoke(ex).ConfigureAwait(false); } }, cancellationToken); }
/// <summary> /// Begins a communication task with a TCP client using the worker instance to perform requested operations. /// </summary> /// <typeparam name="TService">The contract for the service.</typeparam> /// <param name="worker">The TService instance which will fulfill requested operations.</param> /// <param name="client">The TCP client connection.</param> /// <param name="onRequestReceived">(Optional) Action to perform when a client request has been received.</param> /// <param name="onSendingResponse">(Optional) Action to perform once the worker has processed the operation and prior to sending the server response.</param> /// <param name="onError">(Optional) Action to perform when processing encounters an error.</param> /// <returns>Awaitable task hosting the background processing of the client socket connection.</returns> public static void HandleClient <TService>( this TService worker, TcpClient client, Action <string, byte[][]> onRequestReceived = null, Action <string, byte[]> onSendingResponse = null, Action <Exception> onError = null) { try { using NetworkStream stream = client.GetStream(); // Continue reading as long as client requests are available. OperationWrapper request; while (client.Connected && stream.CanRead && (request = stream.GetWrapperResponse(client.ReceiveBufferSize)) != OperationWrapper.SessionEnded) { onRequestReceived?.Invoke(request.Operation, request.Arguments); object result = worker.InvokeRequest(request); // Now send back a response. var response = OperationWrapper.FromResult(request.Operation, result); onSendingResponse?.Invoke(request.Operation, response.Result); stream.SendWrapperRequest(response); stream.Flush(); } } catch (Exception ex) { if (onError == null) { throw; } onError(ex); } }