diff --git a/packages/pub_sub/README.md b/packages/pub_sub/README.md index 1c75f028..3976bd1f 100644 --- a/packages/pub_sub/README.md +++ b/packages/pub_sub/README.md @@ -1,50 +1,53 @@ -# pub_sub -[![Pub](https://img.shields.io/pub/v/pub_sub.svg)](https://pub.dartlang.org/packages/pub_sub) -[![build status](https://travis-ci.org/thosakwe/pub_sub.svg)](https://travis-ci.org/thosakwe/pub_sub) +# angel3_pub_sub +[![version](https://img.shields.io/badge/pub-v4.0.1-brightgreen)](https://pub.dartlang.org/packages/angel3_pub_sub) +[![Null Safety](https://img.shields.io/badge/null-safety-brightgreen)](https://dart.dev/null-safety) +[![Gitter](https://img.shields.io/gitter/room/angel_dart/discussion)](https://gitter.im/angel_dart/discussion) + +[![License](https://img.shields.io/github/license/dukefirehawk/angel)](https://github.com/dukefirehawk/angel/tree/angel3/packages/pub_sub/LICENSE) Keep application instances in sync with a simple pub/sub API. # Installation -Add `pub_sub` as a dependency in your `pubspec.yaml` file: +Add `angel3_pub_sub` as a dependency in your `pubspec.yaml` file: ```yaml dependencies: - pub_sub: ^1.0.0 + angel3_pub_sub: ^3.0.0 ``` Then, be sure to run `pub get` in your terminal. # Usage -`pub_sub` is your typical pub/sub API. However, `pub_sub` enforces authentication of every -request. It is very possible that `pub_sub` will run on both servers and in the browser, -or on a platform like Flutter. Thus, there are provisions available to limit +`pub_sub` is your typical pub/sub API. However, `angel3_pub_sub` enforces authentication of every +request. It is very possible that `angel3_pub_sub` will run on both servers and in the browser, +or on a platform angel3_pub_sublike Flutter. Thus, there are provisions available to limit access. -**Be careful to not leak any `pub_sub` client ID's if operating over a network.** +**Be careful to not leak any `angel3_pub_sub` client ID's if operating over a network.** If you do, you risk malicious users injecting events into your application, which could ultimately spell *disaster*. -A `pub_sub` server can operate across multiple *adapters*, which take care of interfacing data over different +A `angel3_pub_sub` server can operate across multiple *adapters*, which take care of interfacing data over different media. For example, a single server can handle pub/sub between multiple Isolates and TCP Sockets, as well as WebSockets, simultaneously. ```dart -import 'package:pub_sub/pub_sub.dart' as pub_sub; +import 'package:angel3_pub_sub/angel3_pub_sub.dart' as pub_sub; main() async { - var server = new pub_sub.Server([ - new FooAdapter(...), - new BarAdapter(...) + var server = pub_sub.Server([ + FooAdapter(...), + BarAdapter(...) ]); - server.addAdapter(new BazAdapter(...)); + server.addAdapter( BazAdapter(...)); // Call `start` to activate adapters, and begin handling requests. server.start(); } ``` ### Trusted Clients -You can use `package:pub_sub` without explicitly registering +You can use `package:angel3_pub_sub` without explicitly registering clients, *if and only if* those clients come from trusted sources. Clients via `Isolate` are always trusted. @@ -53,10 +56,10 @@ Clients via `package:json_rpc_2` must be explicitly marked as trusted (i.e. using an IP whitelist mechanism): ```dart -new JsonRpc2Adapter(..., isTrusted: false); +JsonRpc2Adapter(..., isTrusted: false); // Pass `null` as Client ID when trusted... -new pub_sub.IsolateClient(null); +pub_sub.IsolateClient(null); ``` ### Access Control @@ -66,7 +69,7 @@ if it is impossible to register new clients, then malicious users cannot grant t privileges within the system. ```dart -import 'package:pub_sub/pub_sub.dart' as pub_sub; +import 'package:angel3_pub_sub/angel3_pub_sub.dart' as pub_sub; main() async { // ... @@ -87,25 +90,25 @@ main() async { ## Isolates If you are just running multiple instances of a server, -use `package:pub_sub/isolate.dart`. +use `package:angel3_pub_sub/isolate.dart`. You'll need one isolate to be the master. Typically this is the first isolate you create. ```dart import 'dart:io'; import 'dart:isolate'; -import 'package:pub_sub/isolate.dart' as pub_sub; -import 'package:pub_sub/pub_sub.dart' as pub_sub; +import 'package:angel3_pub_sub/isolate.dart' as pub_sub; +import 'package:angel3_pub_sub/angel3_pub_sub.dart' as pub_sub; -main() async { +void main() async { // Easily bring up a server. - var adapter = new pub_sub.IsolateAdapter(); - var server = new pub_sub.Server([adapter]); + var adapter = pub_sub.IsolateAdapter(); + var server = pub_sub.Server([adapter]); // You then need to create a client that will connect to the adapter. // Each isolate in your application should contain a client. for (int i = 0; i < Platform.numberOfProcessors - 1; i++) { - server.registerClient(new pub_sub.ClientInfo('client$i')); + server.registerClient(pub_sub.ClientInfo('client$i')); } // Start the server. @@ -123,7 +126,7 @@ main() async { void isolateMain(List args) { var client = - new pub_sub.IsolateClient('client${args[0]}', args[1] as SendPort); + pub_sub.IsolateClient('client${args[0]}', args[1] as SendPort); // The client will connect automatically. In the meantime, we can start subscribing to events. client.subscribe('user::logged_in').then((sub) { @@ -138,14 +141,14 @@ void isolateMain(List args) { ## JSON RPC 2.0 If you are not running on isolates, you need to import -`package:pub_sub/json_rpc_2.dart`. This library leverages `package:json_rpc_2` and +`package:angel3_pub_sub/json_rpc_2.dart`. This library leverages `package:json_rpc_2` and `package:stream_channel` to create clients and servers that can hypothetically run on any medium, i.e. WebSockets, or TCP Sockets. -Check out `test/json_rpc_2_test.dart` for an example of serving `pub_sub` over TCP sockets. +Check out `test/json_rpc_2_test.dart` for an example of serving `angel3_pub_sub` over TCP sockets. # Protocol -`pub_sub` is built upon a simple RPC, and this package includes +`angel3_pub_sub` is built upon a simple RPC, and this package includes an implementation that runs via `SendPort`s and `ReceivePort`s, as well as one that runs on any `StreamChannel`. @@ -213,7 +216,7 @@ Clients can send the following (3) methods: * `unsubscribe` (`subscription_id`:string): Unsubscribe from an event you previously subscribed to. * `publish` (`event_name`:string, `value`:any): Publish an event to all other clients who are subscribed. -The client and server in `package:pub_sub/isolate.dart` must make extra +The client and server in `package:angel3_pub_sub/isolate.dart` must make extra provisions to keep track of client ID's. Since `SendPort`s and `ReceivePort`s do not have any sort of guaranteed-unique ID's, new clients must send their `SendPort` to the server before sending any requests. The server then responds diff --git a/packages/pub_sub/example/main.dart b/packages/pub_sub/example/main.dart index 6a1db68a..9d4afd51 100644 --- a/packages/pub_sub/example/main.dart +++ b/packages/pub_sub/example/main.dart @@ -1,19 +1,19 @@ import 'dart:io'; import 'dart:isolate'; -import 'package:pub_sub/isolate.dart' as pub_sub; -import 'package:pub_sub/pub_sub.dart' as pub_sub; +import 'package:angel3_pub_sub/isolate.dart' as pub_sub; +import 'package:angel3_pub_sub/angel3_pub_sub.dart' as pub_sub; -main() async { +void main() async { // Easily bring up a server. - var adapter = new pub_sub.IsolateAdapter(); - var server = new pub_sub.Server([adapter]); + var adapter = pub_sub.IsolateAdapter(); + var server = pub_sub.Server([adapter]); // You then need to create a client that will connect to the adapter. // Every untrusted client in your application should be pre-registered. // // In the case of Isolates, however, those are always implicitly trusted. for (int i = 0; i < Platform.numberOfProcessors - 1; i++) { - server.registerClient(new pub_sub.ClientInfo('client$i')); + server.registerClient(pub_sub.ClientInfo('client$i')); } // Start the server. @@ -22,8 +22,9 @@ main() async { // Next, let's start isolates that interact with the server. // // Fortunately, we can send SendPorts over Isolates, so this is no hassle. - for (int i = 0; i < Platform.numberOfProcessors - 1; i++) + for (var i = 0; i < Platform.numberOfProcessors - 1; i++) { await Isolate.spawn(isolateMain, [i, adapter.receivePort.sendPort]); + } // It's possible that you're running your application in the server isolate as well: isolateMain([0, adapter.receivePort.sendPort]); @@ -31,8 +32,7 @@ main() async { void isolateMain(List args) { // Isolates are always trusted, so technically we don't need to pass a client iD. - var client = - new pub_sub.IsolateClient('client${args[0]}', args[1] as SendPort); + var client = pub_sub.IsolateClient('client${args[0]}', args[1] as SendPort); // The client will connect automatically. In the meantime, we can start subscribing to events. client.subscribe('user::logged_in').then((sub) { diff --git a/packages/pub_sub/lib/pub_sub.dart b/packages/pub_sub/lib/angel3_pub_sub.dart similarity index 100% rename from packages/pub_sub/lib/pub_sub.dart rename to packages/pub_sub/lib/angel3_pub_sub.dart diff --git a/packages/pub_sub/lib/src/isolate/client.dart b/packages/pub_sub/lib/src/isolate/client.dart index 3c8e7d55..3e3b8131 100644 --- a/packages/pub_sub/lib/src/isolate/client.dart +++ b/packages/pub_sub/lib/src/isolate/client.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'dart:collection'; import 'dart:isolate'; import 'package:uuid/uuid.dart'; -import '../../pub_sub.dart'; +import '../../angel3_pub_sub.dart'; /// A [Client] implementation that communicates via [SendPort]s and [ReceivePort]s. class IsolateClient extends Client { diff --git a/packages/pub_sub/lib/src/isolate/server.dart b/packages/pub_sub/lib/src/isolate/server.dart index 6d75b9f1..3d38af6d 100644 --- a/packages/pub_sub/lib/src/isolate/server.dart +++ b/packages/pub_sub/lib/src/isolate/server.dart @@ -1,7 +1,7 @@ import 'dart:async'; import 'dart:isolate'; import 'package:uuid/uuid.dart'; -import '../../pub_sub.dart'; +import '../../angel3_pub_sub.dart'; /// A [Adapter] implementation that communicates via [SendPort]s and [ReceivePort]s. class IsolateAdapter extends Adapter { diff --git a/packages/pub_sub/lib/src/json_rpc/client.dart b/packages/pub_sub/lib/src/json_rpc/client.dart index e9146e04..7a601059 100644 --- a/packages/pub_sub/lib/src/json_rpc/client.dart +++ b/packages/pub_sub/lib/src/json_rpc/client.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:stream_channel/stream_channel.dart'; import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc_2; import 'package:uuid/uuid.dart'; -import '../../pub_sub.dart'; +import '../../angel3_pub_sub.dart'; /// A [Client] implementation that communicates via JSON RPC 2.0. class JsonRpc2Client extends Client { diff --git a/packages/pub_sub/lib/src/json_rpc/server.dart b/packages/pub_sub/lib/src/json_rpc/server.dart index e7080ce1..f038d72b 100644 --- a/packages/pub_sub/lib/src/json_rpc/server.dart +++ b/packages/pub_sub/lib/src/json_rpc/server.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:stream_channel/stream_channel.dart'; import 'package:json_rpc_2/json_rpc_2.dart' as json_rpc_2; import 'package:uuid/uuid.dart'; -import '../../pub_sub.dart'; +import '../../angel3_pub_sub.dart'; /// A [Adapter] implementation that communicates via JSON RPC 2.0. class JsonRpc2Adapter extends Adapter { diff --git a/packages/pub_sub/pubspec.yaml b/packages/pub_sub/pubspec.yaml index 7973b778..5062381f 100644 --- a/packages/pub_sub/pubspec.yaml +++ b/packages/pub_sub/pubspec.yaml @@ -1,15 +1,14 @@ -name: pub_sub +name: angel3_pub_sub version: 3.0.0 description: Keep application instances in sync with a simple pub/sub API. -homepage: https://github.com/thosakwe/pub_sub -publish_to: none +homepage: https://github.com/dukefirehawk/angel/tree/angel3/packages/pub_sub environment: sdk: '>=2.12.0 <3.0.0' dependencies: json_rpc_2: ^3.0.0 stream_channel: ^2.1.0 uuid: ^3.0.4 - collection: ^1.15.0-nullsafety.4 + collection: ^1.15.0 dev_dependencies: pedantic: ^1.11.0 - test: ^1.17.3 + test: ^1.17.4 diff --git a/packages/pub_sub/test/isolate_test.dart b/packages/pub_sub/test/isolate_test.dart index 5a3ac8d8..ecb31ec4 100644 --- a/packages/pub_sub/test/isolate_test.dart +++ b/packages/pub_sub/test/isolate_test.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import 'package:pub_sub/pub_sub.dart'; -import 'package:pub_sub/isolate.dart'; +import 'package:angel3_pub_sub/angel3_pub_sub.dart'; +import 'package:angel3_pub_sub/isolate.dart'; import 'package:test/test.dart'; void main() { diff --git a/packages/pub_sub/test/json_rpc_2_test.dart b/packages/pub_sub/test/json_rpc_2_test.dart index ff02ae3b..ee6a33b2 100644 --- a/packages/pub_sub/test/json_rpc_2_test.dart +++ b/packages/pub_sub/test/json_rpc_2_test.dart @@ -1,8 +1,8 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'package:pub_sub/pub_sub.dart'; -import 'package:pub_sub/json_rpc_2.dart'; +import 'package:angel3_pub_sub/angel3_pub_sub.dart'; +import 'package:angel3_pub_sub/json_rpc_2.dart'; import 'package:stream_channel/stream_channel.dart'; import 'package:test/test.dart';