Beispiel #1
0
        /// <summary>
        /// 读取客户端请求流的下一帧数据
        /// </summary>
        /// <returns></returns>
        public async Task <bool> MoveNext()
        {
            try
            {
                _val = RpcKit.ParseBytes <object>(await RpcServerKit.ReadFrame(_invoker.Context.Request.BodyReader));
                return(true);
            }
            catch { }

            return(false);
        }
Beispiel #2
0
        /// <summary>
        /// 处理http rpc请求
        /// </summary>
        /// <returns></returns>
        public async Task Handle()
        {
            // 解析rpc参数
            if (!await ParseParams())
            {
                return;
            }

            // 校验授权
            if (!await IsAuthenticated())
            {
                // 未授权
                Context.Response.StatusCode = 401;
                return;
            }

            // 流模式先返回心跳帧,心跳帧为第一帧,避免客户端认为连接超时
            if (Api.CallMode != ApiCallMode.Unary)
            {
                await RpcServerKit.WriteHeartbeat(Context.Response.BodyWriter);
            }

            // 创建整个http请求期间有效的数据包,提供不同位置共享对象
            Bag  bag   = new Bag(this);
            bool isSuc = true;

            switch (Api.CallMode)
            {
            case ApiCallMode.Unary:
                isSuc = await new UnaryHandler(this).Call();
                break;

            case ApiCallMode.ServerStream:
                isSuc = await new ServerStreamHandler(this).Call();
                break;

            case ApiCallMode.ClientStream:
                isSuc = await new ClientStreamHandler(this).Call();
                break;

            case ApiCallMode.DuplexStream:
                isSuc = await new DuplexStreamHandler(this).Call();
                break;
            }
            // Api调用结束后释放资源
            await bag.Close(isSuc);
        }
Beispiel #3
0
        /// <summary>
        /// 反序列化json格式的调用参数,请求的第一帧
        /// </summary>
        /// <returns></returns>
        async Task <bool> ParseParams()
        {
            try
            {
                byte[] data = await RpcServerKit.ReadFrame(Context.Request.BodyReader);

                DoParse(data);
                return(true);
            }
            catch (Exception ex)
            {
                Log.Error(ex, _errParse);
                await Response(ApiResponseType.Error, 0, _errParse);

                return(false);
            }
        }
Beispiel #4
0
        /// <summary>
        /// 向客户端写入一帧
        /// </summary>
        /// <param name="p_message">支持序列化的对象</param>
        /// <returns></returns>
        public async Task <bool> Write(object p_message)
        {
            // 请求已关闭,无法写入
            if (_invoker.Context.RequestAborted.IsCancellationRequested)
            {
                return(false);
            }

            try
            {
                await RpcServerKit.WriteFrame(_invoker.Context.Response.BodyWriter, p_message);

                return(true);
            }
            catch { }

            return(false);
        }
Beispiel #5
0
        /// <summary>
        /// 向客户端输出响应
        /// </summary>
        /// <param name="p_responseType">结果标志:0成功,1错误,2警告提示</param>
        /// <param name="p_elapsed">耗时</param>
        /// <param name="p_content">内容</param>
        /// <returns></returns>
        public Task Response(ApiResponseType p_responseType, long p_elapsed, object p_content)
        {
            try
            {
                byte[] data;
                using (var stream = new MemoryStream())
                {
                    using (var writer = new Utf8JsonWriter(stream, JsonOptions.UnsafeWriter))
                    {
                        writer.WriteStartArray();

                        // 0成功,1错误,2警告提示
                        writer.WriteNumberValue((int)p_responseType);
                        // 耗时
                        writer.WriteNumberValue(p_elapsed);
                        // 内容
                        JsonRpcSerializer.Serialize(p_content, writer);

                        writer.WriteEndArray();
                    }
                    data = stream.ToArray();
                }
                bool compress = data.Length > RpcKit.MinCompressLength;

                // 超过长度限制时执行压缩
                if (compress)
                {
                    var ms = new MemoryStream();
                    using (GZipStream zs = new GZipStream(ms, CompressionMode.Compress))
                    {
                        zs.Write(data, 0, data.Length);
                    }
                    data = ms.ToArray();
                }

                // 写入响应流
                return(RpcServerKit.WriteFrame(Context.Response.BodyWriter, data, compress));
            }
            catch (Exception ex)
            {
                Log.Error(ex, "向客户端输出信息时异常!");
            }
            return(Task.CompletedTask);
        }