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

Unable to start subscription server with graphql-ws protocol #7924

Open
Mr-Goldberg opened this issue Aug 26, 2024 · 1 comment
Open

Unable to start subscription server with graphql-ws protocol #7924

Mr-Goldberg opened this issue Aug 26, 2024 · 1 comment

Comments

@Mr-Goldberg
Copy link

Mr-Goldberg commented Aug 26, 2024

Issue Description

Hi, everyone!

I was following your guide to build server that supports subscriptions. The guide clearly says that server protocol will be graphql-ws. But I've found that the server protocol is graphql-transport-ws somehow.

I was struggling with this error on iOS side while trying to use subscription:
WebSocketError(payload: nil, error: Optional(ApolloWebSocket.WebSocket.WSError(type: ApolloWebSocket.WebSocket.WSError.ErrorType.protocolError, message: "Subprotocol not acceptable", code: 4406)), kind: ApolloWebSocket.WebSocketError.ErrorKind.networkError)

Then I've added logs to the socket-server, and got a log output every second (3 outputs included):

httpServer.on("upgrade", (request, socket, head) => {
 log("upgrade", `${process.uptime()}`);
});
wsServer.on("headers", (headers, request) => {
 log("headers", `${process.uptime()} ${request.url} ${headers}`);
});
wsServer.on("connection", (socket) => {
  log("connection", `${process.uptime()} ${socket.protocol}`);
});

/*
Server log outputs:

headers 725.661031564 /graphql-subscriptions HTTP/1.1 101 Switching Protocols,Upgrade: websocket,Connection: Upgrade,Sec-WebSocket-Accept: tcCOpw8jUeBCdBQ75HQ+wMGIaZM=
connection 725.661696195 
upgrade 725.661997484

headers 726.716486181 /graphql-subscriptions HTTP/1.1 101 Switching Protocols,Upgrade: websocket,Connection: Upgrade,Sec-WebSocket-Accept: S+RHY3SevLMmJTL4RqNG+Z9kZDU=
connection 726.716700488 
upgrade 726.716893474

headers 727.787623637 /graphql-subscriptions HTTP/1.1 101 Switching Protocols,Upgrade: websocket,Connection: Upgrade,Sec-WebSocket-Accept: nERyI3oVrUocy4fhOuXRxZXcB8Q=
connection 727.787844604 
upgrade 727.788041241
*/

Accidentally I've switched the protocol in iOS to .graphql_transport_ws and IT WORKED! Also, there was only the single output from socket logs (which included the protocol name):

headers 748.008532921 /graphql-subscriptions HTTP/1.1 101 Switching Protocols,Upgrade: websocket,Connection: Upgrade,Sec-WebSocket-Accept: vUamFHP1yb9kEcnbWzNk9uTAXdQ=,Sec-WebSocket-Protocol: graphql-transport-ws
connection 748.008724487 graphql-transport-ws
upgrade 748.00883525

So, the question is: Am I doing something wrong (probably server-side), or is there an issue with the Server code, which somehow uses the old .graphql_transport_ws protocol?

Here is the minimal Server code: Sandbox

I was not assembling an iOS example, as there may have been an obvious error in my server code. But here's how I am assembling the Apollo client:

let graphQlEndpoint = URL(string: "https://9xd9fj-4000.csb.app/graphql")!
let graphQlWsEndpoint = URL(string: "wss://9xd9fj-4000.csb.app/graphql-subscriptions")!

let client = URLSessionClient()
let cache = InMemoryNormalizedCache()
let store = ApolloStore(cache: cache)
let provider = DefaultInterceptorProvider(client: client, store: store)
let transport = RequestChainNetworkTransport(interceptorProvider: provider, endpointURL: graphQlEndpoint)
let webSocket = WebSocket(url: graphQlWsEndpoint, protocol: .graphql_ws)

let webSocketTransport = WebSocketTransport(websocket: webSocket)

let splitTransport = SplitNetworkTransport(
    uploadingNetworkTransport: transport,
    webSocketNetworkTransport: webSocketTransport
)

return ApolloClient(networkTransport: splitTransport, store: store)

Link to Reproduction

Sandbox

Reproduction Steps

Set up the Apollo server by this guide and try to use a subscription.

Expected result:
Subscription is working with the graphql-ws protocol

Actual result:

  • Subscription is not working (sub-protocol error: the server expects the graphql-transport-ws protocol)
  • The client tries to establish the socket connection once a second and fails
@Mr-Goldberg
Copy link
Author

Well, ok, I found the issue 😅

I've mistakenly used .graphql_ws instead of .graphql_transport_ws in the iOS client.
However, this is a counterintuitive option, as the correct options for the Apollo Server and Apollo Studio Explorer are graphql-ws, but for iOS, it is vice versa.

Screenshot 2024-08-26 at 21 08 43

It would be great if you could address this issue - maybe by providing:

  1. Clearer sub-protocol option for iOS client
  2. Clearer error message for iOS client
  3. Error message for the server about an attempt to connect with the wrong sub-protocol

Also, I want to thank the team - this is a great product! It was easy to set up and a pleasure to use! Before this issue 😅

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

7 participants
@Mr-Goldberg and others