之后,建立了一个控制台项目作为grpc请求发起请求的客户端,并且建立
了一个web项目作为接收请求的服务端,测试成功,两边可以相互通讯。
然后
我另外新建一个web项目,希望将其代替前面建立的控制台项目,作为
grpc请求发起请求的客户端,也就是说grpc的客户端和服务端都是web项目
,但是却出现了问题:
客户端发起请求时报“Status(StatusCode="Internal", Detail="Request protocol 'HTTP/1.1' is not supported.")”
这样的错误。
我们知道grpc是通过http/2进行通讯的,难道两个web端之间不能使用http/2进行通讯?
我百度了一下,似乎有个叫gRPC-Web的东西可以解决这个问题,是不是客户端和服务端
都需要gRPC-Web进行封装呢,还是只是服务端?
上面提到参考文章有源码可下,地址为https://github.com/stulzq/BlogDemos
提问:各位能人是否有遇到我这种情况, 请求解决方案和经验指点,期待大伙的意见,感谢!
基于最新版ChatGPT4的回答,望采纳!!!有其他问题也可以询问我哦💕(最新版更智能,功能更加强大):
您的问题可能是由于两个Web项目之间使用了HTTP/1.1协议导致的,而gRPC需要使用HTTP/2协议才能正常工作。可以尝试在两个Web项目中使用HTTP/2协议来解决这个问题。
可以使用gRPC-Web将gRPC请求转换为HTTP/1.1或HTTP/2请求,并在Web浏览器中使用JavaScript编写gRPC客户端代码。在这种情况下,您需要修改客户端代码以使用gRPC-Web。您可以使用如下命令来生成gRPC-Web代码:
protoc --plugin=protoc-gen-grpc-web=/usr/local/bin/grpc-web-proxy \
--grpc-web_out=import_style=commonjs,mode=grpcwebtext:./ \
path/to/your.proto
此外,您还需要在Web项目中安装并配置gRPC-Web代理,以便将gRPC请求转换为HTTP/1.1或HTTP/2请求。对于Java Web项目,您可以使用grpc-web-java库提供的gRPC-Web代理。
如果您不想使用gRPC-Web,也可以尝试使用WebSocket协议来实现双向通信。WebSocket协议可以在Web浏览器和服务器之间建立持久性的双向连接,并支持二进制数据传输。在这种情况下,您需要使用WebSocket库来实现gRPC客户端和服务器。例如,您可以使用grpc-websocket-proxy来实现gRPC客户端和服务器之间的通信。
综上所述,您可以尝试使用gRPC-Web或WebSocket来实现两个Web项目之间的双向通信。如果您有其他问题或需要更多帮助,请随时提问。
该回答引用ChatGPT
npm install grpc-web
javascript
const grpc = require('grpc');
const grpcWeb = require('grpc-web');
const proto = grpc.load('path/to/your/proto/file.proto');
const server = new grpcWeb.WrappedGrpcServer({
proto,
// your gRPC service implementation
implementation: {
// your gRPC service methods
},
// your gRPC service options
options: {
// your gRPC service options
},
});
server.start();
npm install grpc-web
javascript
const {HelloRequest, HelloReply} = require('path/to/your/proto/file_pb.js');
const {GreeterClient} = require('path/to/your/proto/file_grpc_web_pb.js');
const client = new GreeterClient('http://localhost:8080');
const request = new HelloRequest();
request.setName('World');
client.sayHello(request, {}, (err, response) => {
if (err) {
console.error(err);
} else {
console.log(response.getMessage());
}
});
1、客户端添加 Grpc.Net.Client NuGet 包
2、服务端添加 Grpc.AspNetCore NuGet 包
3、客户端创建GrpcChannel 实例,再创建gRPC 客户端
using Grpc.Net.Client;
var channel = GrpcChannel.ForAddress("https://localhost:5001");
var client = new Greeter.GreeterClient(channel);
4、服务端创建gRPC 服务,在 Startup.cs 中把它添加到应用程序中
using Grpc.Core;
public class GreeterService : Greeter.GreeterBase
{
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
{
return Task.FromResult(new HelloReply
{
Message = "Hello " + request.Name
});
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>();
});
}
}
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
从错误信息中可以看出,问题是客户端请求所用的协议不被支持。这是因为前面建立的控制台项目使用了grpc的原生客户端,而在新建的web项目中,使用的是HTTP客户端,因为http客户端只支持HTTP协议,而grpc需要使用http/2进行通讯。
要解决这个问题,可以使用gRPC-Web技术,它允许在web上使用grpc,具体来说,gRPC-Web在客户端和浏览器之间提供了一个网关来转换http/1.1为grpc-web,它可以让grpc在浏览器中运行。
在使用gRPC-Web之前,需要先启用gRPC-Web代理,而在服务端上,则不需要额外的处理,因为服务端的grpc实现是不变的。
详细步骤如下:
可以使用Envoy或nginx等代理服务器来启用gRPC-Web代理,以Envoy为例,参考以下配置:
http_filters:
...
- name: envoy.grpc_web
可以使用improbable-eng/grpc-web库来对gRPC-Web客户端进行配置。具体方法请参考:https://github.com/grpc/grpc-web#javascript-client
下面是一个使用gRPC-Web的示例:
服务端代码:
from concurrent import futures
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def SayHelloAgain(self, request, context):
return helloworld_pb2.HelloReply(message='Hello again, %s!' % request.name)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port('[::]:50051')
server.start()
server.wait_for_termination()
if __name__ == '__main__':
serve()
客户端代码:
<!DOCTYPE html>
<html>
<head>
<title>gRPC-Web Example</title>
<!-- Load gRPC-Web directly from the server -->
<script src="https://unpkg.com/grpc-web/dist/grpc-web.js"></script>
<!-- Load our generated code, under /proto/ -->
<script src="./helloworld_pb.js"></script>
<script src="./helloworld_grpc_web_pb.js"></script>
<script>
function run() {
var request = new helloworld_pb.HelloRequest();
request.setName(document.getElementById("name").value);
var client = new helloworld_grpc_web.GreeterClient('http://localhost:8080');
client.sayHello(request, {}, (err, response) => {
document.getElementById("output").innerHTML = response.getMessage();
});
}
</script>
</head>
<body>
<input type="text" id="name"><button onclick="run()">send</button>
<p id="output"></p>
</body>
</html>
注意这里的客户端使用了gRPC-Web库,页面中也包含了相关的JavaScript脚本。在这种情况下,客户端会请求localhost:8080/grpc-web,Envoy会代理请求,将HTTP/1.1协议转换为gRPC-Web协议。
参考资料:
https://www.grpc.io/docs/platforms/web/basics/
https://developers.google.com/web/showcase/2016/grpc
如果我的回答解决了您的
gRPC-Webd确实可以解决这个问题,感谢大家的帮忙!