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

Subscription not working, only connected #1361

Closed
rrifafauzikomara opened this issue Jul 20, 2023 · 12 comments
Closed

Subscription not working, only connected #1361

rrifafauzikomara opened this issue Jul 20, 2023 · 12 comments
Assignees
Labels
⌛ reproduction needed Issue is subtle and requires a true accessible reproduction to debug needs more info More information is required Priority: Waiting to be assigned To be inside the next release process, it need to be marked with some level of priority ⚡ websocket Web Socket Related
Milestone

Comments

@rrifafauzikomara
Copy link

I am creating a subscription with GraphQL, and I need to consume that subscription with Flutter, but I don't know how to do that on the Flutter side. But I can understand doing that on Postman.

Here are the steps to test a subscription on Postman:

  1. Connect to wss
  2. Send a Message by clicking Send button.
  3. Trigger any API, then the subscription will listen new data.

And here's the result for above steps.
enter image description here

And if I do these steps, the subscription will not work.

  1. Connect to wss
  2. Trigger any API, then the subscription will not listen any data.

And here's the result for above steps.
enter image description here

As u can see, even though connected to the wss, if i dont send the Message by clicked the Send button, the subscription will not work.

When I try to implement the subscription in Flutter side, seems only connected to the wss, here's the result.

flutter: Initialising connection

So my question is, how to send the Message like from Postman but in Flutter side?

Here's the Message data.

{
  "id": "{{$randomUUID}}",
  "payload": {
    "data": "{\"query\":\"subscription updateCheckout { onUpdateCheckout(userId: \\\"{{userId}}\\\") { userId createdAt amount checkoutId maxAllowedAmount maxAvailableAmount message state trancheId }}\"}",
    "extensions": {
      "authorization": {
        "Authorization": "{{cognitoIdToken}}",
        "host": "{{apiHost}}"
      }
    }
  },
  "type": "start"
}

Here's the Schema from AWS.

subscription MySubscription {
  onUpdateCheckout(userId: $userId) {
    createdAt
    checkoutId
    maxAllowedAmount
    maxAvailableAmount
    message
    state
    trancheId
  }
}

And here's my Flutter code to impl the subscription.

Future<Map<String, dynamic>> subscription() async {
    try {
      final graphqlEndpoint = 'https://BASEURL/graphql';
      final subscriptionEndpoint =
          'wss://BASEURL/graphql/realtime?header=<EncodedHeader>&payload=e30=';
      var currentToken = _token();

      final HttpLink httpLink = HttpLink(
        graphqlEndpoint,
        defaultHeaders: {
          'Authorization': "Bearer $currentToken",
          'Sec-WebSocket-Protocol': GraphQLProtocol.graphqlWs,
        },
      );

      final WebSocketLink webSocketLink = WebSocketLink(
        subscriptionEndpoint,
        config: SocketClientConfig(
          autoReconnect: true,
          serializer: AppSyncRequest(uuid: 'uuid', token: currentToken),
          inactivityTimeout: const Duration(seconds: 60),
          headers: kIsWeb
              ? null
              : {
                  'Authorization': "Bearer $currentToken",
                  'Sec-WebSocket-Protocol': GraphQLProtocol.graphqlWs,
                },
          initialPayload: {
            'Authorization': currentToken,
          },
        ),
        subProtocol: GraphQLProtocol.graphqlWs,
      );

      final AuthLink authLink =
          AuthLink(getToken: () => 'Bearer $currentToken');

      final Link linkSplitted = authLink.split(
        (request) => request.isSubscription,
        webSocketLink,
        httpLink,
      );

      final graphQLCache = GraphQLCache();

      final client = GraphQLClient(
        link: linkSplitted,
        cache: graphQLCache,
        defaultPolicies: DefaultPolicies(
          watchQuery: Policies(fetch: FetchPolicy.noCache),
          query: Policies(fetch: FetchPolicy.noCache),
          mutate: Policies(fetch: FetchPolicy.noCache),
          subscribe: Policies(fetch: FetchPolicy.noCache),
        ),
        alwaysRebroadcast: true,
      );

      const checkOutSubscription = r'''
subscription MySubscription {
  onUpdateCheckout(userId: $userId) {
    createdAt
    checkoutId
    maxAllowedAmount
    maxAvailableAmount
    message
    state
    trancheId
  }
}
''';

      final options = SubscriptionOptions(
        document: gql(checkOutSubscription),
        variables: {
          "userId": "userId",
        },
      );

      final result = client.subscribe(options);
      Map<String, dynamic> data = {};
      result.listen(
        (event) {
          // not triggered
          data = event.data ?? {};
          if (data.isNotEmpty) {
            // not triggered
          }
        },
        cancelOnError: true,
      );

      return Future.value(data);
    } on Exception {
      rethrow;
    }
  }
@vincenzopalazzo
Copy link
Collaborator

I did not check the code but do you try to use the correct ws protocol? Check the ws link dart docs about the protocol name

@rrifafauzikomara
Copy link
Author

rrifafauzikomara commented Jul 20, 2023

I copy the ws link from console log (IDE) when I running that code, then paste it to Postman, it's success connected. Then I send the Message by clicked Send button, it's success get the data as well.

Seems the problem is I need to send the Message as well like in the Postman, but not sure how to do it on ur pacakge, any suggestion?

For the ws protocol, yea i use the correct one, which is 'Sec-WebSocket-Protocol': GraphQLProtocol.graphqlWs, same like in the Postman, which is Sec-WebSocket-Protocol:graphql-ws

@vincenzopalazzo
Copy link
Collaborator

vincenzopalazzo commented Jul 20, 2023

I am not able to see what is the ws server protocol, can you post it?

In addition, I am having a hard time with the postman image because I do not use it, so with postman you are able to get the result in the correct way? If yes we need a reproducer for this

@vincenzopalazzo vincenzopalazzo added ⚡ websocket Web Socket Related Priority: Waiting to be assigned To be inside the next release process, it need to be marked with some level of priority labels Jul 20, 2023
@vincenzopalazzo vincenzopalazzo self-assigned this Jul 20, 2023
@vincenzopalazzo vincenzopalazzo added this to the v5.2.0 milestone Jul 20, 2023
@rrifafauzikomara
Copy link
Author

rrifafauzikomara commented Jul 20, 2023

how i can get/see the ws server protocol? I do not understand what u mean, basically, I just follow ur example from here: https://github.com/zino-hofmann/graphql-flutter/tree/main/examples/starwars

but adding some extra code like header, token, etc. I already share all my code above.

Yea from the postman I can get the data because I can send the Message by clicked the Send button, but how to do it in ur package?

@vincenzopalazzo
Copy link
Collaborator

The demo is not working, so you should follow this #1204 I should merge it, too also, if needs some work.

In addition, you should know what protocol the server speaks, I can not know. Try to change the protocol to the last one and see what happens

Yea from the postman I can get the data because I can send the Message by clicked the Send button, but how to do it in ur package?

Sorry I do not know what Send a message means!

@rrifafauzikomara
Copy link
Author

rrifafauzikomara commented Jul 20, 2023

in my example code above, I already share the ws protocol, which is graphql-ws.

Screenshot 2023-07-20 at 7 07 00 PM

Sorry I do not know what Send a message means!

How can u understand it if u never see my Postman image, lol.

Here's the image, pls see the red line!
aaa

@vincenzopalazzo
Copy link
Collaborator

No please no screenshot, try to change the protocol with the second one and see the server has the new protocol enabled

@rrifafauzikomara
Copy link
Author

So you hope to understand other developer's problems that use ur package without wanting to see the problem? lol

Change protocol to what? in postman, we use that on the header. In my example code above, I use it as well. And for the ws link we use the same for both flutter code and also postman.

ws link: wss://BASEURL/graphql/realtime?header=<EncodedHeader>&payload=e30=
ws protocol: graphql-ws

@vincenzopalazzo
Copy link
Collaborator

So you hope to understand other developer's problems that use ur package without wanting to see the problem? lol

You are asking to me to spend time on your problem without know what ws protocol your server speak, by putting a couple of picture together and without know that the library support another protocol (and this mean that you never see the docs)

static const String graphqlTransportWs = "graphql-transport-ws";

every time I regret spending some time on an issue without reproducer. So if you want me to see the problem you need to reproduce an issue with an example that I can run.

P.S: It is missing also the library version, so this is not a bug report, but a consultancy request it you want it you should consider using the email.

Cheers

@vincenzopalazzo vincenzopalazzo added ⌛ reproduction needed Issue is subtle and requires a true accessible reproduction to debug needs more info More information is required labels Jul 20, 2023
@rrifafauzikomara
Copy link
Author

Sorry about that, prev I don't understand what ws meant, but if u see my code and also I already share it with u right, the ws protocol u mean was graphql-ws or GraphQLProtocol.graphqlWs.

by putting a couple of picture together

Like I said before right, the subscription working on Postman, then I want to explain it to u so I put a couple of pictures together with some description about that pictures, but u say Sorry I do not know what Send a message means! :(. Then how I can explaint the Postman and my case to u? coz the Message and Send what I mean before is only available on the screenshot :(.

But yeah nvm, thanks for spending ur time to take a look on my issue. The problem before it's not because ws protocol i think, but because I don't add connectFn in the WebSocketLink. After I add this, now I can get the data from subs. But seems got another error from that.

flutter: Rifa 3: {"type":"connection_ack","payload":{"connectionTimeoutMs":300000}}
flutter: Rifa 3: {"type":"ka"}
flutter: Rifa 3: {"type":"error","payload":{"errors":[{"errorType":"UnsupportedOperation","message":"unknown not supported through the realtime channel"}]}}

Is this error coming from my server or from the package (need more setup)?

@vincenzopalazzo
Copy link
Collaborator

Just checking the error on stack overflow https://stackoverflow.com/questions/74293606/websocket-with-appsync-error-unsupportedoperation-unknown-not-supported-throug

It is the server, please see the PR that are open to check how to do authentication

@vincenzopalazzo
Copy link
Collaborator

I am closing this because you solved the problem by looking at your code. feel free to if you had a reproducer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
⌛ reproduction needed Issue is subtle and requires a true accessible reproduction to debug needs more info More information is required Priority: Waiting to be assigned To be inside the next release process, it need to be marked with some level of priority ⚡ websocket Web Socket Related
Projects
None yet
Development

No branches or pull requests

2 participants