diff --git a/chat_example/README.md b/chat_example/README.md index e0e6ea71..c89c58f3 100644 --- a/chat_example/README.md +++ b/chat_example/README.md @@ -2,13 +2,14 @@ A simple chat client (dart2js) and server (Dart VM). -Launch the server: +Launch pub serve and the server, in separate terminals: -`dart bin/main.dart` +`pub serve` -This will immediately work in Dartium, connect to `localhost:26199`. To build for js, run: +`dart bin/main.dart` -`pub build` +You can now load the app in Dartium or any modern browser at +http://localhost:26199. When developing, run diff --git a/chat_example/lib/server/http_server_connection.dart b/chat_example/lib/server/http_server_connection.dart index 20d99491..1d85ba17 100644 --- a/chat_example/lib/server/http_server_connection.dart +++ b/chat_example/lib/server/http_server_connection.dart @@ -3,21 +3,21 @@ // license that can be found in the LICENSE file. import 'dart:async'; -import 'dart:io'; import 'package:chat_example/server/server_connection.dart'; +import 'package:web_socket_channel/web_socket_channel.dart'; /// [ServerConnection] using a web socket. class HttpServerConnection implements ServerConnection { - final WebSocket _webSocket; + final WebSocketChannel _webSocketChannel; final StreamController _streamController = new StreamController(); @override String username; - HttpServerConnection(this._webSocket) { - _webSocket.listen((data) { + HttpServerConnection(this._webSocketChannel) { + _webSocketChannel.stream.listen((data) { _streamController.add(data); }); } @@ -27,11 +27,11 @@ class HttpServerConnection implements ServerConnection { @override void sendToClient(String data) { - _webSocket.add(data); + _webSocketChannel.sink.add(data); } @override void close() { - _webSocket.close(); + _webSocketChannel.sink.close(); } } diff --git a/chat_example/lib/server/resource_server.dart b/chat_example/lib/server/resource_server.dart index 41a0b200..9d843c12 100644 --- a/chat_example/lib/server/resource_server.dart +++ b/chat_example/lib/server/resource_server.dart @@ -3,73 +3,36 @@ // license that can be found in the LICENSE file. import 'dart:async'; -import 'dart:io'; -import 'package:package_resolver/package_resolver.dart'; -import 'package:route/server.dart'; +import 'package:shelf/shelf.dart'; +import 'package:shelf/shelf_io.dart' as io; +import 'package:shelf_proxy/shelf_proxy.dart'; +import 'package:shelf_web_socket/shelf_web_socket.dart'; +import 'package:web_socket_channel/web_socket_channel.dart'; -typedef void SocketReceiver(WebSocket webSocket); +typedef void SocketReceiver(WebSocketChannel webSocket); -/// Serves static resources for the built_value chat example. +/// Resource server for the built_value chat example. /// -/// Also, accepts web socket connections. +/// Proxies to pub serve for most requests. Accepts web socket connections. class ResourceServer { /// Serves resources, passing new sockets to [socketReceiver]. Future start(SocketReceiver socketReceiver) async { - final server = await HttpServer.bind('localhost', 26199); - print('Serving at localhost:26199.'); - final router = new Router(server); - router.serve('/').listen((request) { - request.response - ..statusCode = HttpStatus.OK - ..headers.contentType = - new ContentType('text', 'html', charset: 'utf-8') - ..write(new File('web/index.html').readAsStringSync()) - ..close(); + final cascade = new Cascade() + // Web socket handler will do nothing for non-websocket requests, so + // just add it in the cascade at the top. + .add(webSocketHandler(socketReceiver)) + // Anything else goes to pub serve. + .add(proxyHandler(Uri.parse('http://localhost:8080'))) + // If that didn't work, must be a problem with pub serve. + .add((_) { + print('Request failed. Check pub serve output for errors.'); + return new Response.notFound(''); }); - router.serve('/main.dart').listen((request) { - request.response - ..statusCode = HttpStatus.OK - ..headers.contentType = - new ContentType('application', 'dart', charset: 'utf-8') - ..write(new File('web/main.dart').readAsStringSync()) - ..close(); + await io.serve(cascade.handler, 'localhost', 26199).then((server) { + print('Serving at http://${server.address.host}:${server.port}. Please ' + 'also run pub serve on port 8080.'); }); - - router.serve(new RegExp(r'.*\.dart$')).listen((request) async { - var path = request.uri.path; - - if (path.startsWith('/packages/')) { - final package = path - .replaceFirst('/packages/', '') - .replaceFirst(new RegExp('/.*'), ''); - final resolved = await PackageResolver.current.packagePath(package); - path = resolved + '/lib' + path.replaceFirst('/packages/$package', ''); - } else { - path = '.$path'; - } - - request.response - ..statusCode = HttpStatus.OK - ..headers.contentType = - new ContentType('application', 'dart', charset: 'utf-8') - ..write(new File(path).readAsStringSync()) - ..close(); - }); - - router.serve('/main.css').listen((request) { - request.response - ..statusCode = HttpStatus.OK - ..headers.contentType = new ContentType('text', 'css', charset: 'utf-8') - ..write(new File('web/main.css').readAsStringSync()) - ..close(); - }); - - router - .serve('/ws') - .transform( - new WebSocketTransformer(compression: CompressionOptions.OFF)) - .listen(socketReceiver); } } diff --git a/chat_example/pubspec.yaml b/chat_example/pubspec.yaml index 9e314f62..5f3b7ebb 100644 --- a/chat_example/pubspec.yaml +++ b/chat_example/pubspec.yaml @@ -10,13 +10,16 @@ environment: sdk: '>=1.8.0 <2.0.0' dependencies: - built_collection: '^1.0.0' + browser: ^0.10.0 + built_collection: ^1.0.0 built_value: ^0.4.3 - package_resolver: ^1.0.0 - route: '>=0.4.6' + shelf: ^0.6.0 + shelf_proxy: ^0.1.0 + shelf_web_socket: ^0.2.1 + web_socket_channel: ^1.0.0 dev_dependencies: - build: '^0.4.0' + build: ^0.4.0 built_value_generator: ^0.4.3 source_gen: '>=0.5.0+03 <0.6.0' test: any