/// <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);
            }
        }
Ejemplo n.º 2
0
        /// <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);
            }
        }