Ejemplo n.º 1
0
        /// <summary>
        /// Process a byte[] request which contains the json data.
        /// </summary>
        /// <param name="serviceName">The name of the service.</param>
        /// <param name="requestData">The request data</param>
        /// <param name="cancellationToken">The cancellation token which can cancel this method.</param>
        /// <returns>The response data.</returns>
        public async Task <byte[]> ProcessAsync(string serviceName, byte[] requestData, CancellationToken cancellationToken)
        {
            if (_router == null)
            {
                throw new NullReferenceException("The router is null");
            }
            if (Logger.DebugMode)
            {
                var requestString = Encoding.UTF8.GetString(requestData);
                Logger.WriteDebug($"Receive request data:{requestString}");
            }

            await using var requestStream = new MemoryStream(requestData);
            var requests = await JsonRpcCodec.DecodeRequestsAsync(requestStream, cancellationToken).ConfigureAwait(false);

            var responses = await _router.DispatchRequestsAsync(serviceName, requests, cancellationToken).ConfigureAwait(false);

            var responseData = await JsonRpcCodec.EncodeResponsesAsync(responses, cancellationToken).ConfigureAwait(false);

            if (Logger.DebugMode)
            {
                var responseString = Encoding.UTF8.GetString(responseData);
                Logger.WriteDebug($"Response data sent:{responseString}");
            }
            return(responseData);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Write rpc responses back to the client.
 /// </summary>
 /// <param name="context">The http context</param>
 /// <param name="responses">The responses to write back.</param>
 /// <param name="cancellationToken">The cancel token which will cancel this method.</param>
 /// <returns>Void</returns>
 private async Task WriteRpcResponsesAsync(IJsonRpcHttpContext context, JsonRpcResponse[] responses, CancellationToken cancellationToken = default)
 {
     try
     {
         var resultData = await JsonRpcCodec.EncodeResponsesAsync(responses, cancellationToken).ConfigureAwait(false);
         await WriteRpcResultAsync(context, resultData, cancellationToken).ConfigureAwait(false);
     }
     catch (Exception ex)
     {
         Logger.WriteWarning($"Write rpc response back to client error:{ex}");
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Write a group of JsonRpcHttpResponse to remote side.
        /// </summary>
        /// <param name="context">The context of the http.</param>
        /// <param name="responses">A group of JsonRpcHttpResponses to write.</param>
        /// <returns>Void</returns>
        public async Task WriteResponses(object context, JsonRpcResponse[] responses)
        {
            var resultData = await JsonRpcCodec.EncodeResponsesAsync(responses).ConfigureAwait(false);

            await WriteResultAsync(context, resultData).ConfigureAwait(false);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Handle data from websocket and return result data to remote client.
        /// </summary>
        /// <param name="requestPath">The request path from the http request.</param>
        /// <param name="router">The router to handle the request data.</param>
        /// <param name="socket">The connected websocket.</param>
        /// <param name="cancellationToken">The cancellation token which can cancel this method</param>
        protected async Task HandleWebSocketAsync(string requestPath, IJsonRpcRouter router, WebSocket socket, CancellationToken cancellationToken = default)
        {
            try
            {
                var serviceName = GetRpcServiceName(requestPath);
                if (string.IsNullOrEmpty(serviceName) || !router.ServiceExists(serviceName))
                {
                    Logger.WriteWarning($"Service {serviceName} does not exist.");
                    throw new InvalidOperationException($"Service [{serviceName}] does not exist.");
                }

                byte[]       receiveBuffer = null;
                MemoryStream inputStream   = null;
                // While the WebSocket connection remains open run a simple loop that receives data and sends it back.
                while (socket.State == WebSocketState.Open)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    receiveBuffer ??= ArrayPool <byte> .Shared.Rent(1024);

                    inputStream ??= new MemoryStream();
                    var receiveResult = await socket.ReceiveAsync(receiveBuffer, cancellationToken).ConfigureAwait(false);

                    if (receiveResult.MessageType == WebSocketMessageType.Close)
                    {
                        await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", cancellationToken).ConfigureAwait(false);
                    }
                    else if (receiveResult.MessageType == WebSocketMessageType.Text)
                    {
                        await socket.CloseAsync(WebSocketCloseStatus.InvalidMessageType, "Cannot accept text frame", cancellationToken).ConfigureAwait(false);
                    }
                    else
                    {
                        await inputStream.WriteAsync(receiveBuffer, 0, receiveResult.Count, cancellationToken).ConfigureAwait(false);

                        //handle stream
                        if (receiveResult.EndOfMessage)
                        {
                            //Release resources.
                            var requestData = inputStream.ToArray();
                            await inputStream.DisposeAsync().ConfigureAwait(false);

                            inputStream = null;
                            ArrayPool <byte> .Shared.Return(receiveBuffer);

                            receiveBuffer = null;

                            if (Logger.DebugMode)
                            {
                                var requestString = Encoding.UTF8.GetString(requestData);
                                Logger.WriteDebug($"Receive request data: {requestString}");
                            }

                            var requests = await JsonRpcCodec.DecodeRequestsAsync(requestData, cancellationToken).ConfigureAwait(false);

                            var responses = await router.DispatchRequestsAsync(serviceName, requests, cancellationToken).ConfigureAwait(false);

                            var responseData = await JsonRpcCodec.EncodeResponsesAsync(responses, cancellationToken).ConfigureAwait(false);

                            await socket.SendAsync(responseData, WebSocketMessageType.Binary, true, cancellationToken).ConfigureAwait(false);

                            if (Logger.DebugMode)
                            {
                                var resultString = Encoding.UTF8.GetString(responseData);
                                Logger.WriteDebug($"Response data sent:{resultString}");
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.WriteError($"Handle request {requestPath} error: {ex.Message}");
            }
            finally
            {
                socket.Dispose();
                Logger.WriteVerbose("Remote websocket closed.");
            }
        }