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