angel_websocket 2.0.2

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 82

angel_websocket #

Pub build status

WebSocket plugin for Angel.

This plugin broadcasts events from hooked services via WebSockets.

In addition, it adds itself to the app's IoC container as AngelWebSocket, so that it can be used in controllers as well.

WebSocket contexts are add to req.properties as 'socket'.

Usage #

Server-side

import "package:angel_framework/angel_framework.dart";
import "package:angel_websocket/server.dart";

main() async {
  var app = new Angel();

  var ws = new AngelWebSocket();
  
  // This is a plug-in. It hooks all your services,
  // to automatically broadcast events.
  await app.configure(ws.configureServer);
  
  // Listen for requests at `/ws`.
  app.all('/ws', ws.handleRequest);
}

Filtering events is easy with hooked services. Just return a bool, whether synchronously or asynchronously.

myService.properties['ws:filter'] = (HookedServiceEvent e, WebSocketContext socket) async {
  return true;
}

myService.index({
  'ws:filter': (e, socket) => ...;
});

Adding Handlers within a Controller

WebSocketController extends a normal Controller, but also listens to WebSockets.

import 'dart:async';
import "package:angel_framework/angel_framework.dart";
import "package:angel_websocket/server.dart";

@Expose("/")
class MyController extends WebSocketController {
  // A reference to the WebSocket plug-in is required.
  MyController(AngelWebSocket ws):super(ws);
  
  @override
  void onConnect(WebSocketContext socket) {
    // On connect...
  }
  
  // Dependency injection works, too..
  @ExposeWs("read_message")
  void sendMessage(WebSocketContext socket, WebSocketAction action, Db db) async {
    socket.send(
      "found_message",
      db.collection("messages").findOne(where.id(action.data['message_id'])));
  }

  // Event filtering
  @ExposeWs("foo")
  void foo() {
    broadcast(new WebSocketEvent(...), filter: (socket) async => ...);
  }
}

Client Use

This repo also provides two client libraries browser and io that extend the base angel_client interface, and allow you to use a very similar API on the client to that of the server.

The provided clients also automatically try to reconnect their WebSockets when disconnected, which means you can restart your development server without having to reload browser windows.

They also provide streams of data that pump out filtered data as it comes in from the server.

Clients can even perform authentication over WebSockets.

In the Browser

import "package:angel_websocket/browser.dart";

main() async {
  Angel app = new WebSockets("/ws");
  await app.connect();

  var Cars = app.service("api/cars");

  Cars.onCreated.listen((car) => print("New car: $car"));

  // Happens asynchronously
  Cars.create({"brand": "Toyota"});

  // Authenticate a WebSocket, if you were not already authenticated...
  app.authenticateViaJwt('<some-jwt>');

  // Listen for arbitrary events
  app.on['custom_event'].listen((event) {
    // For example, this might be sent by a
    // WebSocketController.
    print('Hi!');
  });
}

CLI Client

import "package:angel_framework/common.dart";
import "package:angel_websocket/io.dart";

// You can include these in a shared file and access on both client and server
class Car extends Model {
  int year;
  String brand, make;

  Car({this.year, this.brand, this.make});

  @override String toString() => "$year $brand $make";
}

main() async {
  Angel app = new WebSockets("/ws");

  // Wait for WebSocket connection...
  await app.connect();

  var Cars = app.service("api/cars", type: Car);

  Cars.onCreated.listen((Car car) {
      // Automatically deserialized into a car :)
      //
      // I just bought a new 2016 Toyota Camry!
      print("I just bought a new $car!");
  });

  // Happens asynchronously
  Cars.create({"year": 2016, "brand": "Toyota", "make": "Camry"});

  // Authenticate a WebSocket, if you were not already authenticated...
  app.authenticateViaJwt('<some-jwt>');
}

2.0.2 #

  • Update stream_channel to 2.0.0.
  • Use angel_framework^@2.0.0-rc.0.

2.0.1 #

  • Add reconnectOnClose and reconnectinterval parameters in top-level WebSockets constructors.
  • Close WebSocketExtraneousEventHandler.
  • Add onAuthenticated to server-side.

2.0.0 #

  • Update to work with client@2.0.0.

2.0.0-alpha.8 #

  • Support for WebSockets over HTTP/2 (though in practice this doesn't often happen, if ever).

2.0.0-alpha.7 #

  • Replace WebSocketSynchronizer with StreamChannel<WebSocketEvent>.

2.0.0-alpha.6 #

  • Explicit import of import 'package:http/io_client.dart' as http;

2.0.0-alpha.5 #

  • Update http dependency.

2.0.0-alpha.4 #

  • Remove package:json_god.
  • Make WebSocketContext take any StreamChannel.
  • Strong typing updates.

2.0.0-alpha.3 #

  • Directly import Angel HTTP.

2.0.0-alpha.2 #

  • Updated for the next version of angel_client.

2.0.0-alpha.1 #

  • Refactorings for updated Angel 2 versions.
  • Remove package:dart2_constant.

2.0.0-alpha #

  • Depend on Dart 2 and Angel 2.

1.1.2 #

  • Dart 2 updates.
  • Added handleClient, which is nice for external implementations that plug into AngelWebSocket.

1.1.1 #

  • Deprecated unwrap.
  • Service streams now pump out e.data, rather than the actual event.

1.1.0+1 #

  • Added unwrap.

example/main.dart

import 'dart:io';
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_framework/http.dart';
import 'package:angel_framework/http2.dart';
import 'package:angel_websocket/server.dart';
import 'package:file/local.dart';
import 'package:logging/logging.dart';

main(List<String> args) async {
  var app = new Angel();
  var http = new AngelHttp(app);
  var ws = new AngelWebSocket(app, sendErrors: !app.environment.isProduction);
  var fs = const LocalFileSystem();
  app.logger = new Logger('angel_websocket');

  // This is a plug-in. It hooks all your services,
  // to automatically broadcast events.
  await app.configure(ws.configureServer);

  app.get('/', (req, res) => res.streamFile(fs.file('example/index.html')));

  // Listen for requests at `/ws`.
  app.get('/ws', ws.handleRequest);

  app.fallback((req, res) => throw AngelHttpException.notFound());

  ws.onConnection.listen((socket) {
    socket.onData.listen((x) {
      socket.send('pong', x);
    });
  });

  if (args.contains('http2')) {
    var ctx = new SecurityContext()
      ..useCertificateChain('dev.pem')
      ..usePrivateKey('dev.key', password: 'dartdart');

    try {
      ctx.setAlpnProtocols(['h2'], true);
    } catch (e, st) {
      app.logger.severe(
        'Cannot set ALPN protocol on server to `h2`. The server will only serve HTTP/1.x.',
        e,
        st,
      );
    }

    var http2 = new AngelHttp2(app, ctx);
    http2.onHttp1.forEach(http.handleRequest);
    await http2.startServer('127.0.0.1', 3000);
    print('Listening at ${http2.uri}');
  } else {
    await http.startServer('127.0.0.1', 3000);
    print('Listening at ${http.uri}');
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  angel_websocket: ^2.0.2

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter packages get

Alternatively, your editor might support pub get or flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:angel_websocket/angel_websocket.dart';
  
Version Uploaded Documentation Archive
2.0.2 Apr 18, 2019 Go to the documentation of angel_websocket 2.0.2 Download angel_websocket 2.0.2 archive
2.0.1 Feb 3, 2019 Go to the documentation of angel_websocket 2.0.1 Download angel_websocket 2.0.1 archive
2.0.0 Jan 6, 2019 Go to the documentation of angel_websocket 2.0.0 Download angel_websocket 2.0.0 archive
1.1.2 Jul 10, 2018 Go to the documentation of angel_websocket 1.1.2 Download angel_websocket 1.1.2 archive
1.1.1 Dec 21, 2017 Go to the documentation of angel_websocket 1.1.1 Download angel_websocket 1.1.1 archive
1.1.0+1 Dec 10, 2017 Go to the documentation of angel_websocket 1.1.0+1 Download angel_websocket 1.1.0+1 archive
1.1.0 Dec 7, 2017 Go to the documentation of angel_websocket 1.1.0 Download angel_websocket 1.1.0 archive
1.0.8 Jun 30, 2017 Go to the documentation of angel_websocket 1.0.8 Download angel_websocket 1.0.8 archive
1.0.7 Jun 3, 2017 Go to the documentation of angel_websocket 1.0.7 Download angel_websocket 1.0.7 archive
1.0.6+1 Apr 23, 2017 Go to the documentation of angel_websocket 1.0.6+1 Download angel_websocket 1.0.6+1 archive

All 45 versions...

Popularity:
Describes how popular the package is relative to other packages. [more]
70
Health:
Code health derived from static analysis. [more]
90
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
82
Learn more about scoring.

We analyzed this package on Apr 24, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.2.0
  • pana: 0.12.14

Platforms

Detected platforms: Flutter, web, other

No platform restriction found in primary library package:angel_websocket/angel_websocket.dart.

Health suggestions

Fix lib/base_websocket_client.dart. (-6.78 points)

Analysis of lib/base_websocket_client.dart reported 14 hints, including:

line 99 col 5: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

line 100 col 5: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

line 101 col 5: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

line 102 col 5: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

line 103 col 5: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

Fix lib/server.dart. (-1.99 points)

Analysis of lib/server.dart reported 4 hints:

line 390 col 7: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

line 431 col 11: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

line 433 col 11: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

line 446 col 9: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

Fix lib/websocket_context.dart. (-1.99 points)

Analysis of lib/websocket_context.dart reported 4 hints:

line 44 col 5: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

line 45 col 5: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

line 46 col 5: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

line 48 col 5: Future results in async function bodies must be awaited or marked unawaited using package:pedantic.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev <3.0.0
angel_auth ^2.0.0-alpha 2.1.5
angel_client ^2.0.0-alpha 2.0.2
angel_framework ^2.0.0-rc.0 2.0.0-rc.8
angel_http_exception ^1.0.0 1.1.0
http >=0.11.0 <0.13.0 0.12.0+2
merge_map ^1.0.0 1.0.2
meta ^1.0.0 1.1.7
stream_channel ^2.0.0 2.0.0
web_socket_channel ^1.0.0 1.0.12
Transitive dependencies
angel_route 3.0.6
async 2.2.0
charcode 1.1.2
code_buffer 1.0.1
collection 1.14.11
combinator 1.1.0
convert 2.1.1
crypto 2.0.6
dart2_constant 1.0.2+dart2
file 5.0.7
http2 1.0.0
http_parser 3.1.3
http_server 0.9.8+1
intl 0.15.8
json_god 2.0.0-beta+3
matcher 0.12.5
mime 0.9.6+2
mock_request 1.0.5
path 1.6.2
quiver 2.0.3
quiver_hashcode 2.0.0
source_span 1.5.5
stack_trace 1.9.3
string_scanner 1.0.4
term_glyph 1.1.0
tuple 1.0.2
typed_data 1.1.6
uuid 2.0.1
Dev dependencies
angel_container ^1.0.0-alpha 1.0.4
angel_model ^1.0.0 1.0.2
logging ^0.11.0 0.11.3+2
pedantic ^1.0.0 1.5.0
test ^1.0.0