I'm trying to use shelf_route in combination with shelf_web_socket to have both multiple WebSocket endpoints and a REST api on the same webserver.
My current code looks like this (stripped down):
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as io;
import 'package:shelf_route/shelf_route.dart' as route;
import 'package:shelf_web_socket/shelf_web_socket.dart';
void main(List<String> arguments) {
r(shelf.Request re) {
return new shelf.Response.ok('test');
}
var router = (route.router()
..add( '/rest', ['GET'], r)
..add( '/ws', ['GET'], webSocketHandler((ws) {
print('Connected!');
})));
var handler = const shelf.Pipeline()
.addMiddleware(shelf.logRequests())
.addHandler(router.handler);
io.serve(handler, '127.0.0.1', 30091).then((server) {
print('Serving at http://${server.address.host}:${server.port}');
});
}
The code works fine for the REST part. But if I try to connect to the websocket server, I get the following exception:
Error thrown by handler.
Illegal argument(s): webSocketHandler may only be used with a server that supports request hijacking.
package:shelf_web_socket/src/web_socket_handler.dart 53:7 handle
package:shelf_route/shelf_route.dart 294:20 _Route.handle
package:shelf_route/shelf_route.dart 224:24 _handleRequest
dart:isolate _RawReceivePortImpl._handleMessage
At the beginning of a request, hijacking seems to be supported. But the problem comes in combination with the route package.
I tracked the problem down to the Request.change method in the shelf package. It copies a request, but doesn't copy the hijacking handler.
I wonder if this behavior is intentional and I'm using the packages in the wrong way, or if it was missed during writing the package?