anycable / anycable-rails

AnyCable for Ruby on Rails applications
https://anycable.io
MIT License
495 stars 35 forks source link

Flutter app is connecting fine to wss, but actual subscribe is throwing unknown command type errors #171

Closed courtsimas closed 2 years ago

courtsimas commented 2 years ago

My environment

Ruby version: 3.1.2

Rails version: 7.0.3

anycable gem version: 1.2.3

anycable-rails gem version: 1.3.3

grpc gem version: 1.45.0

We've got two heroku apps. One's the websocket version, running the anycable-go, the other's the normals rails app. They share the same redis, and Postgres. All that works great. Your docs were super helpful and completely accurate and didn't take long to get working.

We have a graphql typical stack. Flutter client app (Apollo). We're trying to implement subscriptions.

The initial connection to our wss is just fine. All the right messages in the logs and it stays connected with the keep alive header.

However, when the initial subscription (for example, one we have called contentRequestWasCreated) comes through, we get an "unknown command". We tracked down that error getting thrown in the go/grpc codebase here: https://github.com/anycable/anycable-go/blob/816f7cffca7007d284757e6796615438f55e652c/node/node.go#L115

It looks like that the only commands it'll accept are 'subscribe', 'unsubscribe', and 'message'. But a lot of the typical front end libraries will send connection_init and start and a few others, like disconnect.

We actually get two errors when we first try to subscribe, after the initial successful connection to the websocket. Our flutter graphql library is sending connection_init which the logs just show it doesn't know what to do with it, then the front end sends start with all the typical payload subscribe info. We figured maybe the grpc server was just picky and didn't want to recognize 'start', so we also manually tried overriding the type to be 'subscribe' from the flutter app, ... but still no dice.

Here's a gist of the relevant logs (showing both examples). The only difference is one sends 'start' and one sends 'subscribe'. Both give the same issue though. https://gist.github.com/courtsimas/528fcc6bfa5f501e849e3d57ff1ad90e

I can post some production code if needed, but I figured maybe someone from this repo can just quickly help kick us in the right direction. My questions are: 1) will start work as the default message type which is what the flutter library sends, despite it not being in the anycable-go case switch as an allowed command? 2) why didn't subscribe work when we tried that? Anything look off in those logs that you guys can maybe see that would be preventing our subscriptions from working?

palkan commented 2 years ago

It seems you're using an official Apollo library at the Flutter side, which implements the Apollo protocol.

By default, AnyCable only supports Action Cable protocol; that means, you need to use a custom link to use GraphQL subscriptions; something line this https://graphql-ruby.org/javascript_client/apollo_subscriptions.html#apollo-2--actioncable

However, there is a better alternative: use AnyCable-Go PRO, which supports Apollo protocol: https://docs.anycable.io/anycable-go/apollo (so, you don't need to deal with client-side hacks). We provide a free trial (2 months, could be extended); just get in touch here: https://anycable.io/#pro

courtsimas commented 2 years ago

@palkan thanks sir! You all at Evil Martians are top notch and anycable is awesome!