Esempio n. 1
0
        /// <summary>
        /// 发送json格式的Http Rpc远程调用
        /// </summary>
        /// <typeparam name="T">结果对象的类型</typeparam>
        /// <returns>返回远程调用结果</returns>
        public async Task <T> Call <T>()
        {
            // 远程请求
            byte[] data = null;
            using (var request = CreateRequestMessage())
                using (var content = new PushStreamContent((ws) => RpcClientKit.WriteFrame(ws, _data, _isCompressed)))
                {
                    request.Content = content;
                    HttpResponseMessage response;
                    try
                    {
                        response = await _client.SendAsync(request).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        throw new ServerException("服务器连接失败", $"调用【{_methodName}】时服务器连接失败!\r\n{ex.Message}");
                    }

                    if (response.StatusCode != System.Net.HttpStatusCode.OK)
                    {
#if !SERVER
                        // 无权限时
                        if (response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                        {
                            // 已登录则提示无权限
                            if (Kit.IsLogon)
                            {
                                throw new KnownException($"⚡对【{_methodName}】无访问权限!");
                            }

                            // 跳转到登录页面
                            Kit.Login(true);
                            throw new KnownException("请先登录您的账号!");
                        }
#endif
                        throw new ServerException($"服务器返回状态码:{response.StatusCode}", $"调用【{_methodName}】时返回状态码:{response.StatusCode}");
                    }

                    var stream = await response.Content.ReadAsStreamAsync();

                    data = await RpcClientKit.ReadFrame(stream);

                    response.Dispose();
                }
            return(ParseResult <T>(data));
        }
Esempio n. 2
0
        /// <summary>
        /// 启动Http2协议的远程调用,客户端发送一个请求,服务端返回数据流响应
        /// </summary>
        /// <returns></returns>
        public async Task <ResponseReader> Call()
        {
            try
            {
                using (var request = CreateRequestMessage())
                    using (var content = new PushStreamContent((ws) => RpcClientKit.WriteFrame(ws, _data, _isCompressed)))
                    {
                        // 必须设置 WebAssemblyEnableStreamingResponse 为 true,WASM 才会返回 stream 类型的 response;
                        // 如果不设置,则只在整个response结束时收到一次,无法实现服务器推送流模式!!!参见:
                        // https://github.com/grpc/grpc-dotnet/blob/master/src/Grpc.Net.Client.Web/GrpcWebHandler.cs#L137
                        //
                        // 此限制和服务端无关,只是WASM客户端在收到服务器推送后的处理方式不同,默认response 非 stream模式,参见:
                        // https://github.com/mono/mono/blob/a0d69a4e876834412ba676f544d447ec331e7c01/sdks/wasm/framework/src/System.Net.Http.WebAssemblyHttpHandler/WebAssemblyHttpHandler.cs#L149
                        //
                        // https://github.com/mono/mono/issues/18718
#if WASM
#pragma warning disable CS0618
                        request.Properties["WebAssemblyEnableStreamingResponse"] = true;
#pragma warning restore CS0618
#endif

                        request.Content = content;
                        // 一定是ResponseHeadersRead,否则只在结束时收到一次!!!众里寻他千百度
                        var response = await _client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, CancellationToken.None);

                        response.EnsureSuccessStatusCode();

                        var reader = new ResponseReader(response);
                        // wasm中增加上述设置后返回 stream 正常!
                        await reader.InitStream();

                        return(reader);
                    }
            }
            catch (Exception ex)
            {
                throw new Exception($"调用【{_methodName}】时服务器连接失败!\r\n{ex.Message}");
            }
        }