-
-
Notifications
You must be signed in to change notification settings - Fork 772
Description
Problem
When using WebSocket with the graphql-ws protocol (for GraphQL subscriptions), browsers reject the connection with:
WebSocket connection failed: Error during WebSocket handshake:
Sent non-empty 'Sec-WebSocket-Protocol' header but no response was received
This happens because crossws's node adapter has handleProtocols: () => false hardcoded:
// crossws/dist/adapters/node.mjs
const wss = options.wss || new _WebSocketServer({
noServer: true,
handleProtocols: () => false, // ← Problem
...options.serverOptions // ← Solution exists but not exposed
});The ws library uses handleProtocols to negotiate WebSocket subprotocols. When it returns false, browsers reject the handshake even if we manually add Sec-WebSocket-Protocol header in the upgrade hook.
Current Workaround
Adding the header manually in the upgrade hook works for Node.js clients but not for browsers:
defineWebSocketHandler({
upgrade(request) {
const protocol = request.headers.get('sec-websocket-protocol')
if (protocol?.includes('graphql-transport-ws')) {
return {
headers: { 'Sec-WebSocket-Protocol': 'graphql-transport-ws' }
}
}
}
})Proposed Solution
Expose serverOptions in Nitro's WebSocket configuration so users can customize the crossws adapter:
// nitro.config.ts
export default defineNitroConfig({
features: {
websocket: true
},
websocket: {
serverOptions: {
handleProtocols: (protocols) => {
if (protocols.has('graphql-transport-ws')) {
return 'graphql-transport-ws'
}
return false
}
}
}
})Or at minimum, allow passing serverOptions to the crossws adapter in the runtime presets.
Use Case
This is needed for GraphQL subscriptions over WebSocket using the graphql-ws protocol, which is the standard for:
- GraphQL Yoga
- Apollo Server
- Any GraphQL server implementing the graphql-ws spec
Environment
- Nitro: 3.0.1-alpha.1
- crossws: 0.4.1
- Node.js: 24.x
Related
- crossws adapter code: https://github.com/unjs/crossws/blob/main/src/adapters/node.ts
- graphql-ws protocol: https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md