Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] stream #760

Open
solarhell opened this issue Jun 27, 2024 · 10 comments
Open

[Question] stream #760

solarhell opened this issue Jun 27, 2024 · 10 comments

Comments

@solarhell
Copy link

I have a connectrpc backend server that provides frontend access via Nginx. Now I'm finding some issues with one-way streaming. I checked the documentation suggesting that I should use apache or enovy to proxy the stream.
Is it possible to use the stream method properly if access is provided directly by connectrpc's http.Server without any proxy server software?
FYI, the one-way stream is like rpc StreamChat(StreamChatRequest) returns (stream StreamChatResponse);
and the err code in chrome shows: net::ERR_HTTP2_PROTOCOL_ERROR 200 (OK)

@tahadostifam
Copy link

Hi,
If you used reverse proxy with Nginx you need to specify somehow to use http2. I guess your problem because Nginx uses http1.1 by default and gRPC streams only work with http2.

And can i ask why you use envoy proxy? connectrpc has built-in json gateway it self and does not require external gateways like envoy... but if you want reverse proxy it's different...

@solarhell
Copy link
Author

https://connectrpc.com/docs/faq/#how-do-i-proxy-the-connect-protocol-through-nginx

As the doc said that nginx can't proxy stream. I am using caddy now and it works fine. Next time i will try just use connectrpc's go http server to serve the stream.

@tahadostifam
Copy link

tahadostifam commented Jul 22, 2024

Good to see you fixed it, but you know caddy has really bad performance? If performance is important for your project you are in a big trouble.

Take a look at the litespeed. I don't know it has streaming features but offers good performance.

Good Luck👾🤌🏿

@jhump
Copy link
Member

jhump commented Jul 22, 2024

That error message looks like it may be related to the HTTP/2-related configuration of your nginx server, and not necessarily related to the use of a server-streaming RPC with nginx.

Streaming RPCs typically require end-to-end HTTP/2, which NGINX doesn't support.

IIUC, this statement in the FAQs refers to bidirectional streams, which typically cannot work with HTTP 1.1 since they require full-duplex communication (which is only possible when using HTTP/2 or web sockets). The issue with nginx is that it can only use HTTP/2 when communicating with the client, and only supports HTTP 1.1 when communicating with a backend server. So any incoming HTTP/2 request will be downgraded to HTTP 1.1 when proxied to a backend server.

But one-way streaming operations are half-duplex -- so they can still work with nginx because they can work with HTTP 1.1.

Is it possible to use the stream method properly if access is provided directly by connectrpc's http.Server without any proxy server software?

Yes, streaming definitely works if the client connects directly to the connect server w/out the use of a proxy. A proxy is not necessary for any functionality with connect.

Could you possibly provide more details on the nginx and backend server config? What client are you using -- are you using connect-web and, if so, what protocol is the client configured to use?

@solarhell
Copy link
Author

solarhell commented Jul 23, 2024

here is my openresty config

server {
    listen 80 ; 
    listen 443 ssl http2 ; 
    server_name api.mydomain.com; 
    proxy_set_header Host $host; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header X-Forwarded-Host $server_name; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_http_version 1.1; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "upgrade"; 
    include /www/sites/api.mydomain.com/proxy/*.conf; 
    if ($scheme = http) {
        return 301 https://$host$request_uri; 
    }
    ssl_certificate /www/sites/api.mydomain.com/ssl/fullchain.pem; 
    ssl_certificate_key /www/sites/api.mydomain.com/ssl/privkey.pem; 
    ssl_protocols TLSv1.3 TLSv1.2 TLSv1.1 TLSv1; 
    ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK:!KRB5:!SRP:!CAMELLIA:!SEED; 
    ssl_prefer_server_ciphers on; 
    ssl_session_cache shared:SSL:10m; 
    ssl_session_timeout 10m; 
    error_page 497 https://$host$request_uri; 
    proxy_set_header X-Forwarded-Proto https; 
    add_header Strict-Transport-Security "max-age=31536000"; 
}

my vhost config

location ^~ / {
    proxy_pass http://127.0.0.1:23333; 
    proxy_set_header Host $host; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_set_header REMOTE-HOST $remote_addr; 
    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "upgrade"; 
    proxy_set_header X-Forwarded-Proto $scheme; 
    proxy_http_version 1.1; 
    add_header X-Cache $upstream_cache_status; 
    add_header Strict-Transport-Security "max-age=31536000"; 
}

and in my front-end code, i use connect-web

image image

@jhump
Copy link
Member

jhump commented Jul 24, 2024

These lines in the config look suspicious:

    proxy_set_header Upgrade $http_upgrade; 
    proxy_set_header Connection "upgrade"; 

Do you also have web socket endpoints? IIRC, most browsers and most servers do not actually support web sockets over HTTP/2, so this could be the issue. The "upgrade" request header is not supported with HTTP/2.

@solarhell
Copy link
Author

Yes, i also have websocket endpoints.

I will try to comment the nginx upgrade config and test the one-way stream.

@jhump
Copy link
Member

jhump commented Jul 24, 2024

@solarhell, if you also need to use web sockets, I'd recommend using plain HTTP 1.1 in the nginx config and not trying to use HTTP/2 at all. That should work fine for web sockets and for one-way streaming with Connect.

@tahadostifam
Copy link

Dear @jhump, The streaming documents for nodejs, connect-web is not complete so much on the site. If i work on them would connectrpc.com welcome that?

@jhump
Copy link
Member

jhump commented Jul 24, 2024

@tahadostifam, thank you for offering. I see you already have a PR over inhttps://github.com/connectrpc/connectrpc.com. I'll add comments over there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants