Django Channels. How to respond to a WebSocket open request with a subprotocol?

You have to specify the subprotocol to use in the websocket.accept message. For example, if you subclass channels.generic.websocket.WebsocketConsumer (also works with SyncConsumer) and using a Sec-WebSocket-Protocol of my-protocol:

class MyProtocolConsumer(WebsocketConsumer):
    def websocket_connect(self, message):
        self.base_send({"type": "websocket.accept", "subprotocol": "my-protocol"})

I was having the same problem. The Websocket spec says that if a client asks for a subprotocol then the server must respond to let the client know it supports it. In my case the subprotocol was "graphql-ws"

After digging around in the graphene code it eventually transpired that it is a simple case of adding the following to the settings:

CHANNELS_WS_PROTOCOLS = ["graphql-ws"]

So, just replace the list of protocols with whatever you want to support. Of course once you've done this you actually need to then implement the subprotocol on the server.