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

websockets in grpcwebproxy #180

Merged
merged 5 commits into from Aug 15, 2018

Conversation

Projects
None yet
8 participants
@JCGrant
Contributor

JCGrant commented Apr 26, 2018

I have used these changes in a project at my job, and they seem to work well!

### Enabling Websocket Transport
By default, grpcwebproxy will not use websockets as a trasport layer. To enable

This comment has been minimized.

@johanbrandhorst

johanbrandhorst Apr 26, 2018

Collaborator

transport

@johanbrandhorst

johanbrandhorst Apr 26, 2018

Collaborator

transport

This comment has been minimized.

@JCGrant

JCGrant Apr 26, 2018

Contributor

Good eye!

@JCGrant

JCGrant Apr 26, 2018

Contributor

Good eye!

@@ -34,6 +34,8 @@ var (
runHttpServer = pflag.Bool("run_http_server", true, "whether to run HTTP server")
runTlsServer = pflag.Bool("run_tls_server", true, "whether to run TLS server")
useWebsockets = pflag.Bool("use_websockets", false, "whether to use beta websocket tranport layer")

This comment has been minimized.

@johanbrandhorst

johanbrandhorst Apr 26, 2018

Collaborator

transport 🤔

@johanbrandhorst

johanbrandhorst Apr 26, 2018

Collaborator

transport 🤔

This comment has been minimized.

@JCGrant

JCGrant Apr 26, 2018

Contributor

I have real issues with that word apparently! 😂

@JCGrant

JCGrant Apr 26, 2018

Contributor

I have real issues with that word apparently! 😂

// gRPC-Web compatibility layer with CORS configured to accept on every
wrappedGrpc := grpcweb.WrapServer(grpcServer, grpcweb.WithCorsForRegisteredEndpointsOnly(false))
options := []grpcweb.Option{
// gRPC-Web compatibility layer with CORS configured to accept on every

This comment has been minimized.

@johanbrandhorst

johanbrandhorst Apr 26, 2018

Collaborator

I think you accidentally a word

@johanbrandhorst

johanbrandhorst Apr 26, 2018

Collaborator

I think you accidentally a word

@@ -49,8 +49,7 @@ $GOPATH/bin/grpcwebproxy
### Enabling Websocket Transport
By default, grpcwebproxy will not use websockets as a trasport layer. To enable
websockets, set the `--use_websockets` flag to true
By default, grpcwebproxy will not use websockets as a transport layer. To enable websockets, set the `--use_websockets` flag to true

This comment has been minimized.

@johanbrandhorst

johanbrandhorst Apr 26, 2018

Collaborator

I think a full stop at the end of this sentence would be correct as well.

@johanbrandhorst

johanbrandhorst Apr 26, 2018

Collaborator

I think a full stop at the end of this sentence would be correct as well.

@easyCZ

This comment has been minimized.

Show comment
Hide comment
@easyCZ

easyCZ Apr 26, 2018

Collaborator

Thanks for the PR, looks good. Will test it tomorrow.

Collaborator

easyCZ commented Apr 26, 2018

Thanks for the PR, looks good. Will test it tomorrow.

@timotheecour

This comment has been minimized.

Show comment
Hide comment
@timotheecour

timotheecour May 3, 2018

friendly ping on this

timotheecour commented May 3, 2018

friendly ping on this

@easyCZ

easyCZ approved these changes May 8, 2018

LGTM, @MarcusLongmuir do you mind taking a look?

@bianbian-org

This comment has been minimized.

Show comment
Hide comment
@bianbian-org

bianbian-org May 31, 2018

Contributor

hope merged, thanks!

Contributor

bianbian-org commented May 31, 2018

hope merged, thanks!

@bianbian-org

This comment has been minimized.

Show comment
Hide comment
@bianbian-org

bianbian-org Jun 5, 2018

Contributor

oops, websockets cannot work with Java backend (https is ok).

Contributor

bianbian-org commented Jun 5, 2018

oops, websockets cannot work with Java backend (https is ok).

@bianbian-org

This comment has been minimized.

Show comment
Hide comment
@bianbian-org

bianbian-org Jun 14, 2018

Contributor

@JCGrant need help please. May I ask what is your backend server based? I use a Java-based backend, ws could return Status Code: 101 Switching Protocols, but cannot handle any other requests and disconnect when timeout. ie. proxy always got rpc error: code = Canceled:

grpcwsproxy_1           | time="2018-06-14T14:39:48Z" level=info 
msg="finished streaming call" error="rpc error: code = Canceled desc = context canceled" 
grpc.code=Canceled grpc.method=GetXXX grpc.service=xxx.Service grpc.start_time="2018-06-14T14:38:48Z" grpc.time_ms=59971 span.kind=server system=grpc
Contributor

bianbian-org commented Jun 14, 2018

@JCGrant need help please. May I ask what is your backend server based? I use a Java-based backend, ws could return Status Code: 101 Switching Protocols, but cannot handle any other requests and disconnect when timeout. ie. proxy always got rpc error: code = Canceled:

grpcwsproxy_1           | time="2018-06-14T14:39:48Z" level=info 
msg="finished streaming call" error="rpc error: code = Canceled desc = context canceled" 
grpc.code=Canceled grpc.method=GetXXX grpc.service=xxx.Service grpc.start_time="2018-06-14T14:38:48Z" grpc.time_ms=59971 span.kind=server system=grpc
@JCGrant

This comment has been minimized.

Show comment
Hide comment
@JCGrant

JCGrant Jun 14, 2018

Contributor

@bianbian-org I use a Go backend. Unfortunately, I'm not entirely sure what is causing your issues.

Contributor

JCGrant commented Jun 14, 2018

@bianbian-org I use a Go backend. Unfortunately, I'm not entirely sure what is causing your issues.

@bianbian-org

This comment has been minimized.

Show comment
Hide comment
@bianbian-org

bianbian-org Jun 15, 2018

Contributor

Thanks all the same @JCGrant
I maybe found the problem, finally!
When using grpc-web-client with Websocket as transport, it depends on the finishSendFrame to tell the server that the client has finished sending:

enum WebsocketSignal {
  FINISH_SEND = 1
}

const finishSendFrame = new Uint8Array([1]);
...
    finishSend: () => {
      if (!ws || ws.readyState === ws.CONNECTING) {
        sendQueue.push(WebsocketSignal.FINISH_SEND);
      } else {
        sendToWebsocket(WebsocketSignal.FINISH_SEND);
      }
    },

And in the grpc-web/websocket_wrapper, it waits the signal:

	if len(framePayload) == 1 && framePayload[0] == 1 {
		return 0, io.EOF
	}

However, when call grpc methods, it do not call the finishSend(). So the grpc-web-socket-proxy is always waiting for the finishSendFrame in request till timeout.

When add the finishSendFrame manually, it works!

Contributor

bianbian-org commented Jun 15, 2018

Thanks all the same @JCGrant
I maybe found the problem, finally!
When using grpc-web-client with Websocket as transport, it depends on the finishSendFrame to tell the server that the client has finished sending:

enum WebsocketSignal {
  FINISH_SEND = 1
}

const finishSendFrame = new Uint8Array([1]);
...
    finishSend: () => {
      if (!ws || ws.readyState === ws.CONNECTING) {
        sendQueue.push(WebsocketSignal.FINISH_SEND);
      } else {
        sendToWebsocket(WebsocketSignal.FINISH_SEND);
      }
    },

And in the grpc-web/websocket_wrapper, it waits the signal:

	if len(framePayload) == 1 && framePayload[0] == 1 {
		return 0, io.EOF
	}

However, when call grpc methods, it do not call the finishSend(). So the grpc-web-socket-proxy is always waiting for the finishSendFrame in request till timeout.

When add the finishSendFrame manually, it works!

@alexpdp7

This comment has been minimized.

Show comment
Hide comment
@alexpdp7

alexpdp7 Jun 17, 2018

I've got this working with a Java gRPC server, sent a single request and got a response back correctly.

alexpdp7 commented Jun 17, 2018

I've got this working with a Java gRPC server, sent a single request and got a response back correctly.

@jcloutz

This comment has been minimized.

Show comment
Hide comment
@jcloutz

jcloutz Jul 11, 2018

This works with a C# backend as well, any chance it will be merged soon?

jcloutz commented Jul 11, 2018

This works with a C# backend as well, any chance it will be merged soon?

@MarcusLongmuir MarcusLongmuir merged commit 2cf3019 into improbable-eng:master Aug 15, 2018

1 check passed

continuous-integration/travis-ci/pr The Travis CI build passed
Details
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment