`GraphQLTransportWSHandler` only supports one connection
See original GitHub issueOnce a client has connected to Ariadne through the GraphQLTransportWSHandler
(the newer GraphQL WebSocket protocol), all future attempts to connect by another client will fail, even if the first client has disconnected.
I believe this issue is caused by this section in the code:
It looks like the transport gets tagged as having received an “init” message, even though it seems like the client should be tagged.
Steps to reproduce
I came up with the following sample GraphQL server to demonstrate this issue (using Ariadne v0.16) as a minimal test case:
import asyncio
from ariadne import gql, make_executable_schema, ObjectType, SubscriptionType
from ariadne.asgi import GraphQL
from ariadne.asgi.handlers import GraphQLTransportWSHandler
from starlette.applications import Starlette
from starlette.routing import Route, WebSocketRoute
import uvicorn
type_defs = gql("""
type Query {
hello: String!
}
type Subscription {
counter: Int!
}
""")
query = ObjectType("Query")
@query.field("hello")
def hello_resolver(*_):
return "Hello world"
subscription = SubscriptionType()
@subscription.source("counter")
async def counter_generator(*_):
for i in range(5):
await asyncio.sleep(1)
yield i
@subscription.field("counter")
def counter_resolver(count, *_):
return count
schema = make_executable_schema(type_defs, subscription)
graphql_app = GraphQL(
schema,
debug=True,
websocket_handler=GraphQLTransportWSHandler(),
)
routes = [
Route("/graphql", graphql_app, methods=["GET", "POST"]),
WebSocketRoute("/graphql", endpoint=graphql_app),
]
app = Starlette(debug=True, routes=routes)
if __name__ == "__main__":
uvicorn.run(app, host='0.0.0.0', port=4444)
After creating a file with that script and starting the server with main.py
, I then used websocat to manually trigger the error. First, I connected to the server, manually sent the “connection init” message, then pressed Ctrl-D to disconnect after receiving a “connection ack” message:
$ websocat --protocol 'graphql-ws' 'ws://localhost:4444/graphql'
{"type": "connection_init"}
{"type": "connection_ack"}
^D
Then, I did the same thing as a new client, but did not get the “connection ack”, indicating that the connection was rejected:
$ websocat --protocol 'graphql-ws' 'ws://localhost:4444/graphql'
{"type": "connection_init"}
Running websocat -vv ...
will also show that an error code of 4429 was returned, which lines up with the error code from the graphql_transport_ws.py
file linked above.
Issue Analytics
- State:
- Created a year ago
- Comments:5 (4 by maintainers)
I’m releasing a fix as 0.16.1, thanks everyone!
Sure thing, I just tried out the v0.16.1.b1 release from PyPI and from all my testing, it looks like I am able to connect with multiple different clients now! So from my perspective, that release resolves my issue.
Thanks for coming to such a quick resolution for this issue @rafalp and @pigletto!