Updated websocket

This commit is contained in:
thomashii 2021-07-10 12:32:42 +08:00
parent 0d294adb20
commit 62336e0d53
25 changed files with 158 additions and 223 deletions

View file

@ -52,7 +52,7 @@ abstract class BaseAngelClient extends Angel {
final List<Service> _services = [];
final http.BaseClient client;
final _p = Context(style: Style.url);
final Context _p = Context(style: Style.url);
@override
Stream<AngelAuthResult> get onAuthenticated => _onAuthenticated.stream;
@ -212,7 +212,7 @@ class BaseAngelService<Id, Data> extends Service<Id, Data?> {
final http.BaseClient client;
final AngelDeserializer<Data>? deserializer;
final _p = Context(style: Style.url);
final Context _p = Context(style: Style.url);
final StreamController<List<Data?>> _onIndexed = StreamController();
final StreamController<Data?> _onRead = StreamController(),

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.pub" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Dart SDK" level="project" />
<orderEntry type="library" name="Dart Packages" level="project" />
</component>
</module>

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<includedPredefinedLibrary name="ECMAScript 6" />
<includedPredefinedLibrary name="Node.js Core" />
</component>
</project>

View file

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectInspectionProfilesVisibleTreeState">
<entry key="Project Default">
<profile-state>
<expanded-state>
<State>
<id />
</State>
<State>
<id>General</id>
</State>
<State>
<id>XPath</id>
</State>
</expanded-state>
<selected-state>
<State>
<id>AngularJS</id>
</State>
</selected-state>
</profile-state>
</entry>
</component>
</project>

View file

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/angel_proxy.iml" filepath="$PROJECT_DIR$/.idea/angel_proxy.iml" />
</modules>
</component>
</project>

View file

@ -1,8 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All Tests" type="DartTestRunConfigurationType" factoryName="Dart Test" singleton="true">
<option name="filePath" value="$PROJECT_DIR$" />
<option name="scope" value="FOLDER" />
<option name="testRunnerOptions" value="-j 4" />
<method />
</configuration>
</component>

View file

@ -1,6 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Basic Tests" type="DartTestRunConfigurationType" factoryName="Dart Test" singleton="true">
<option name="filePath" value="$PROJECT_DIR$/test/basic_test.dart" />
<method />
</configuration>
</component>

View file

@ -1,6 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Pub Serve Tests" type="DartTestRunConfigurationType" factoryName="Dart Test" singleton="true">
<option name="filePath" value="$PROJECT_DIR$/test/pub_serve_test.dart" />
<method />
</configuration>
</component>

View file

@ -1,7 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="multiple.dart" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application" singleton="true" nameIsGenerated="true">
<option name="filePath" value="$PROJECT_DIR$/example/multiple.dart" />
<option name="workingDirectory" value="$PROJECT_DIR$" />
<method />
</configuration>
</component>

View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View file

@ -1,11 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Multiple Proxies",
"type": "dart-cli",
"request": "launch",
"program": "${workspaceRoot}/example/multiple.dart"
}
]
}

View file

@ -1,32 +1,43 @@
# 4.0.0
# Change Log
## 4.0.1
* Updated README
## 4.0.0
* Migrated to support Dart SDK 2.12.x NNBD
# 3.0.0
## 3.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
# 2.2.0
## 2.2.0
* Use `http.Client` instead of `http.BaseClient`, and make it an
optional parameter.
* Allow `baseUrl` to accept `Uri` or `String`.
* Add `Proxy.pushState`.
# 2.1.2
## 2.1.2
* Apply lints.
# 2.1.1
## 2.1.1
* Update for framework@2.0.0-alpha.15
# 2.1.0
## 2.1.0
- Use `Uri` instead of archaic `host`, `port`, and `mapTo`. Also cleaner + safer + easier.
* Use `Uri` instead of archaic `host`, `port`, and `mapTo`. Also cleaner + safer + easier.
* Enable WebSocket proxying.
# 2.0.0
## 2.0.0
- Updates for Angel 2. Big thanks to @denkuy!
- Use `package:path` for better path resolution.
* Updates for Angel 2. Big thanks to @denkuy!
* Use `package:path` for better path resolution.
# 1.1.1
## 1.1.1
- Removed reference to `io`; now works with HTTP/2. Thanks to @daniel-v!
* Removed reference to `io`; now works with HTTP/2. Thanks to @daniel-v!

View file

@ -1,12 +1,12 @@
# angel3_proxy
[![version](https://img.shields.io/badge/pub-v4.0.0-brightgreen)](https://pub.dartlang.org/packages/angel3_proxy)
# Angel3 Proxy
[![version](https://img.shields.io/badge/pub-v4.0.1-brightgreen)](https://pub.dartlang.org/packages/angel3_proxy)
[![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/proxy/LICENSE)
Angel middleware to forward requests to another server (i.e. `webdev serve`).
Also supports WebSockets.
Angel middleware to forward requests to another server (i.e. `webdev serve`). Also supports WebSockets.
```dart
import 'package:angel3_proxy/angel3_proxy.dart';
@ -23,15 +23,17 @@ void main() async {
```
You can also restrict the proxy to serving only from a specific root:
```dart
Proxy(baseUrl, publicPath: '/remote');
```
Also, you can map requests to a root path on the remote server:
```dart
Proxy(baseUrl.replace(path: '/path'));
```
Request bodies will be forwarded as well, if they are not empty. This allows things like POST requests to function.
For a request body to be forwarded, the body must not have already been parsed.
For a request body to be forwarded, the body must not have already been parsed.

View file

@ -5,7 +5,7 @@ import 'package:angel3_framework/angel3_framework.dart';
import 'package:angel3_framework/http.dart';
import 'package:http_parser/http_parser.dart';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as p;
import 'package:path/path.dart';
final RegExp _straySlashes = RegExp(r'(^/+)|(/+$)');
final MediaType _fallbackMediaType = MediaType('application', 'octet-stream');
@ -16,6 +16,8 @@ final MediaType _fallbackMediaType = MediaType('application', 'octet-stream');
class Proxy {
String? _prefix;
final Context _p = Context(style: Style.url);
/// The underlying [Client] to use.
final http.Client httpClient;
@ -82,12 +84,12 @@ class Proxy {
Future<bool> handleRequest(RequestContext req, ResponseContext res) {
var path = req.path.replaceAll(_straySlashes, '');
if (_prefix!.isNotEmpty) {
if (!p.isWithin(_prefix!, path) && !p.equals(_prefix!, path)) {
if (_prefix?.isNotEmpty == true) {
if (!_p.isWithin(_prefix!, path) && !_p.equals(_prefix!, path)) {
return Future<bool>.value(true);
}
path = p.relative(path, from: _prefix);
path = _p.relative(path, from: _prefix);
}
return servePath(path, req, res);
@ -98,7 +100,7 @@ class Proxy {
String path, RequestContext req, ResponseContext res) async {
http.StreamedResponse rs;
var uri = baseUrl.replace(path: p.join(baseUrl.path, path));
var uri = baseUrl.replace(path: _p.join(baseUrl.path, path));
try {
if (req is HttpRequestContext &&
@ -123,13 +125,13 @@ class Proxy {
var headers = <String, String>{
'host': uri.authority,
'x-forwarded-for': req.remoteAddress.address,
'x-forwarded-port': req.uri!.port.toString(),
'x-forwarded-port': req.uri?.port.toString() ?? '',
'x-forwarded-host':
req.headers!.host ?? req.headers!.value('host') ?? 'none',
req.headers?.host ?? req.headers?.value('host') ?? 'none',
'x-forwarded-proto': uri.scheme,
};
req.headers!.forEach((name, values) {
req.headers?.forEach((name, values) {
headers[name] = values.join(',');
});
@ -139,8 +141,8 @@ class Proxy {
List<int>? body;
if (!req.hasParsedBody) {
body = await req.body!
.fold<BytesBuilder>(BytesBuilder(), (bb, buf) => bb..add(buf))
body = await req.body
?.fold<BytesBuilder>(BytesBuilder(), (bb, buf) => bb..add(buf))
.then((bb) => bb.takeBytes());
}
@ -149,13 +151,17 @@ class Proxy {
rq.headers['host'] = rq.url.host;
rq.encoding = Utf8Codec(allowMalformed: true);
if (body != null) rq.bodyBytes = body;
if (body != null) {
rq.bodyBytes = body;
}
return httpClient.send(rq);
}
var future = accessRemote();
if (timeout != null) future = future.timeout(timeout!);
if (timeout != null) {
future = future.timeout(timeout!);
}
rs = await future;
} on TimeoutException catch (e, st) {
if (recoverFromDead) return true;

View file

@ -1,7 +1,8 @@
name: angel3_proxy
version: 4.0.0
version: 4.0.1
description: Angel middleware to forward requests to another server (i.e. pub serve).
homepage: https://github.com/dukefirehawk/angel/tree/angel3/packages/proxy
homepage: https://angel3-framework.web.app/
repository: https://github.com/dukefirehawk/angel/tree/angel3/packages/proxy
environment:
sdk: '>=2.12.0 <3.0.0'
dependencies:

View file

@ -9,7 +9,7 @@ import 'package:test/test.dart';
import 'common.dart';
void main() {
Angel? app;
late Angel app;
var client = http.IOClient();
//late HttpServer server;
late HttpServer testServer;
@ -17,7 +17,7 @@ void main() {
setUp(() async {
app = Angel();
var appHttp = AngelHttp(app!);
var appHttp = AngelHttp(app);
testServer = await startTestServer();
@ -33,15 +33,15 @@ void main() {
print('Proxy 1 on: ${proxy1.baseUrl}');
print('Proxy 2 on: ${proxy2.baseUrl}');
app!.all('/proxy/*', proxy1.handleRequest);
app!.all('*', proxy2.handleRequest);
app.all('/proxy/*', proxy1.handleRequest);
app.all('*', proxy2.handleRequest);
app!.fallback((req, res) {
app.fallback((req, res) {
print('Intercepting empty from ${req.uri}');
res.write('intercept empty');
});
app!.logger = Logger('angel');
app.logger = Logger('angel');
Logger.root.onRecord.listen((rec) {
print(rec);
@ -56,7 +56,6 @@ void main() {
tearDown(() async {
await testServer.close(force: true);
//await server.close(force: true);
app = null;
url = null;
});

View file

@ -1,7 +1,7 @@
name: angel3_static
description: This library provides a virtual directory to serve static files for Angel3 framework.
version: 4.0.2
homepage: https://github.com/dukefirehawk/angel
homepage: https://angel3-framework.web.app/
repository: https://github.com/dukefirehawk/angel/tree/angel3/packages/static
environment:
sdk: '>=2.12.0 <3.0.0'

View file

@ -1,63 +1,88 @@
# 4.0.0
# Change Log
## 4.0.1
* Updated README
* Fixed NNBD issues
## 4.0.0
* Migrated to support Dart SDK 2.12.x NNBD
# 3.0.0
## 3.0.0
* Migrated to work with Dart SDK 2.12.x Non NNBD
# 2.0.3
## 2.0.3
* Remove `WebSocketController.plugin`.
* Remove any unawaited futures.
# 2.0.2
## 2.0.2
* Update `stream_channel` to `2.0.0`.
* Use `angel_framework^@2.0.0-rc.0`.
# 2.0.1
## 2.0.1
* Add `reconnectOnClose` and `reconnectinterval` parameters in top-level `WebSockets` constructors.
* Close `WebSocketExtraneousEventHandler`.
* Add onAuthenticated to server-side.
# 2.0.0
## 2.0.0
* Update to work with `client@2.0.0`.
# 2.0.0-alpha.8
## 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
## 2.0.0-alpha.7
* Replace `WebSocketSynchronizer` with `StreamChannel<WebSocketEvent>`.
# 2.0.0-alpha.6
## 2.0.0-alpha.6
* Explicit import of `import 'package:http/io_client.dart' as http;`
# 2.0.0-alpha.5
## 2.0.0-alpha.5
* Update `http` dependency.
# 2.0.0-alpha.4
## 2.0.0-alpha.4
* Remove `package:json_god`.
* Make `WebSocketContext` take any `StreamChannel`.
* Strong typing updates.
# 2.0.0-alpha.3
## 2.0.0-alpha.3
* Directly import Angel HTTP.
# 2.0.0-alpha.2
## 2.0.0-alpha.2
* Updated for the next version of `angel_client`.
# 2.0.0-alpha.1
## 2.0.0-alpha.1
* Refactorings for updated Angel 2 versions.
* Remove `package:dart2_constant`.
# 2.0.0-alpha
## 2.0.0-alpha
* Depend on Dart 2 and Angel 2.
# 1.1.2
## 1.1.2
* Dart 2 updates.
* Added `handleClient`, which is nice for external implementations
that plug into `AngelWebSocket`.
# 1.1.1
## 1.1.1
* Deprecated `unwrap`.
* Service streams now pump out `e.data`, rather than the actual event.
# 1.1.0+1
* Added `unwrap`.
## 1.1.0+1
* Added `unwrap`.

View file

@ -1,29 +1,24 @@
# angel3_websocket
[![version](https://img.shields.io/badge/pub-v4.0.0-brightgreen)](https://pub.dartlang.org/packages/angel3_websocket)
# Angel3 Websocket Library
[![version](https://img.shields.io/badge/pub-v4.0.1-brightgreen)](https://pub.dartlang.org/packages/angel3_websocket)
[![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/websocket/LICENSE)
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 plugin for Angel3. 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
# Usage
**Server-side**
### Server-side
```dart
import "package:angel3_framework/angel3_framework.dart";
import "package:angel3_websocket/server.dart";
main() async {
void main() async {
var app = Angel();
var ws = AngelWebSocket();
@ -38,8 +33,7 @@ main() async {
```
Filtering events is easy with hooked services. Just return a `bool`, whether
synchronously or asynchronously.
Filtering events is easy with hooked services. Just return a `bool`, whether synchronously or asynchronously.
```dart
myService.properties['ws:filter'] = (HookedServiceEvent e, WebSocketContext socket) async {
@ -51,14 +45,14 @@ myService.index({
});
```
**Adding Handlers within a Controller**
#### Adding Handlers within a Controller
`WebSocketController` extends a normal `Controller`, but also listens to WebSockets.
```dart
import 'dart:async';
import "package:angel_framework/angel_framework.dart";
import "package:angel_websocket/server.dart";
import "package:angel3_framework/angel3_framework.dart";
import "package:angel3_websocket/server.dart";
@Expose("/")
class MyController extends WebSocketController {
@ -86,25 +80,22 @@ class MyController extends WebSocketController {
}
```
**Client Use**
### Client Use
This repo also provides two client libraries `browser` and `io` that extend the base
`angel3_client` interface, and allow you to use a very similar API on the client to that of
the server.
This repo also provides two client libraries `browser` and `io` that extend the base `angel3_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.
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**
#### In the Browser
```dart
import "package:angel3_websocket/browser.dart";
main() async {
void main() async {
Angel app = WebSockets("/ws");
await app.connect();
@ -127,7 +118,7 @@ main() async {
}
```
**CLI Client**
#### CLI Client
```dart
import "package:angel3_framework/common.dart";
@ -163,4 +154,4 @@ main() async {
// Authenticate a WebSocket, if you were not already authenticated...
app.authenticateViaJwt('<some-jwt>');
}
}

View file

@ -241,7 +241,7 @@ abstract class BaseWebSocketClient extends BaseAngelClient {
if (_socket == null) {
_queue.addLast(action);
} else {
socket!.sink.add(serialize(action));
socket?.sink.add(serialize(action));
}
}

View file

@ -42,7 +42,7 @@ class WebSockets extends BaseWebSocketClient {
StreamSubscription<Event>? sub;
t = Timer.periodic(Duration(milliseconds: 500), (timer) {
if (!ctrl.isClosed) {
if (wnd.closed!) {
if (wnd.closed == true) {
ctrl.addError(AngelHttpException.notAuthenticated(
message:
errorMessage ?? 'Authentication via popup window failed.'));
@ -60,7 +60,7 @@ class WebSockets extends BaseWebSocketClient {
ctrl.add((e as CustomEvent).detail.toString());
t.cancel();
ctrl.close();
sub!.cancel();
sub?.cancel();
}
});

View file

@ -7,6 +7,7 @@ import 'package:angel3_framework/angel3_framework.dart';
HookedServiceEventListener doNotBroadcast([provider]) {
return (HookedServiceEvent e) {
if (e.params != null && e.params!.containsKey('provider')) {
var eParam = e.params!;
var deny = false;
var providers = provider is Iterable ? provider : [provider];
@ -14,18 +15,15 @@ HookedServiceEventListener doNotBroadcast([provider]) {
if (deny) break;
if (p is Providers) {
deny = deny ||
p == e.params!['provider'] ||
e.params!['provider'] == p.via;
deny = deny || p == eParam['provider'] || eParam['provider'] == p.via;
} else if (p == null) {
deny = true;
} else {
deny =
deny || (e.params!['provider'] as Providers).via == p.toString();
deny = deny || (eParam['provider'] as Providers).via == p.toString();
}
}
e.params!['broadcast'] = false;
eParam['broadcast'] = false;
}
};
}

View file

@ -14,6 +14,7 @@ import 'package:stream_channel/stream_channel.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:logging/logging.dart';
import 'angel3_websocket.dart';
import 'constants.dart';
export 'angel3_websocket.dart';
@ -26,6 +27,8 @@ typedef WebSocketResponseSerializer = String Function(dynamic data);
/// Broadcasts events from [HookedService]s, and handles incoming [WebSocketAction]s.
class AngelWebSocket {
final _log = Logger('AngelWebSocket');
final List<WebSocketContext> _clients = <WebSocketContext>[];
final List<String> _servicesAlreadyWired = [];
@ -258,6 +261,7 @@ class AngelWebSocket {
return null;
}
} catch (e, st) {
_log.severe('Unable to handle unknown action');
catchError(e, st, socket);
}
}
@ -266,15 +270,15 @@ class AngelWebSocket {
Future handleAuth(WebSocketAction action, WebSocketContext socket) async {
if (allowAuth != false &&
action.eventName == authenticateAction &&
action.params!['query'] is Map &&
action.params!['query']['jwt'] is String) {
action.params?['query'] is Map &&
action.params?['query']['jwt'] is String) {
try {
var auth = socket.request.container!.make<AngelAuth>()!;
var jwt = action.params!['query']['jwt'] as String;
AuthToken token;
token = AuthToken.validate(jwt, auth.hmac);
var user = await auth.deserializer!(token.userId as Object);
var user = await auth.deserializer(token.userId as Object);
socket.request
..container!.registerSingleton<AuthToken>(token)
..container!.registerSingleton(user, as: user.runtimeType);
@ -282,6 +286,7 @@ class AngelWebSocket {
socket.send(authenticatedEvent,
{'token': token.serialize(auth.hmac), 'data': user});
} catch (e, st) {
_log.severe('Authentication failed');
catchError(e, st, socket);
}
} else {
@ -345,6 +350,7 @@ class AngelWebSocket {
}
}
} catch (e, st) {
_log.severe('Invalid data');
catchError(e, st, socket);
}
}
@ -353,16 +359,16 @@ class AngelWebSocket {
// Send an error
if (e is AngelHttpException) {
socket.sendError(e);
app!.logger?.severe(e.message, e.error ?? e, e.stackTrace);
app?.logger?.severe(e.message, e.error ?? e, e.stackTrace);
} else if (sendErrors) {
var err = AngelHttpException(e,
message: e.toString(), stackTrace: st, errors: [st.toString()]);
socket.sendError(err);
app!.logger?.severe(err.message, e, st);
app?.logger?.severe(err.message, e, st);
} else {
var err = AngelHttpException(e);
socket.sendError(err);
app!.logger?.severe(e.toString(), e, st);
app?.logger?.severe(e.toString(), e, st);
}
}
@ -383,10 +389,10 @@ class AngelWebSocket {
/// Configures an [Angel] instance to listen for WebSocket connections.
Future configureServer(Angel app) async {
app.container!.registerSingleton(this);
app.container?.registerSingleton(this);
if (runtimeType != AngelWebSocket) {
app.container!.registerSingleton<AngelWebSocket>(this);
app.container?.registerSingleton<AngelWebSocket>(this);
}
// Set up services
@ -397,7 +403,7 @@ class AngelWebSocket {
});
if (synchronizationChannel != null) {
synchronizationChannel!.stream
synchronizationChannel?.stream
.listen((e) => batchEvent(e, notify: false));
}
@ -406,7 +412,7 @@ class AngelWebSocket {
/// Handles an incoming [WebSocketContext].
Future<void> handleClient(WebSocketContext socket) async {
var origin = socket.request.headers!.value('origin');
var origin = socket.request.headers?.value('origin');
if (allowedOrigins != null && !allowedOrigins!.contains(origin)) {
throw AngelHttpException.forbidden(
message:
@ -418,7 +424,7 @@ class AngelWebSocket {
_onConnection.add(socket);
socket.request.container!.registerSingleton<WebSocketContext>(socket);
socket.request.container?.registerSingleton<WebSocketContext>(socket);
socket.channel.stream.listen(
(data) {
@ -451,11 +457,11 @@ class AngelWebSocket {
return false;
} else if (req is Http2RequestContext && res is Http2ResponseContext) {
var connection =
req.headers!['connection']?.map((s) => s.toLowerCase().trim());
var upgrade = req.headers!.value('upgrade')?.toLowerCase();
var version = req.headers!.value('sec-websocket-version');
var key = req.headers!.value('sec-websocket-key');
var protocol = req.headers!.value('sec-websocket-protocol');
req.headers?['connection']?.map((s) => s.toLowerCase().trim());
var upgrade = req.headers?.value('upgrade')?.toLowerCase();
var version = req.headers?.value('sec-websocket-version');
var key = req.headers?.value('sec-websocket-key');
var protocol = req.headers?.value('sec-websocket-protocol');
if (connection == null) {
throw AngelHttpException.badRequest(

View file

@ -1,7 +1,8 @@
name: angel3_websocket
description: Support for using pkg:angel_client with WebSockets. Designed for Angel.
version: 4.0.0
homepage: https://github.com/dukefirehawk/angel/tree/angel3/packages/websocket
description: This library provides WebSockets support for Angel3 framework.
version: 4.0.1
homepage: https://angel3-framework.web.app/
repository: https://github.com/dukefirehawk/angel/tree/angel3/packages/websocket
environment:
sdk: '>=2.12.0 <3.0.0'
dependencies:
@ -15,10 +16,10 @@ dependencies:
stream_channel: ^2.1.0
web_socket_channel: ^2.1.0
collection: ^1.15.0
logging: ^1.0.1
dev_dependencies:
angel3_container: ^3.0.0
angel3_model: ^3.0.0
logging: ^1.0.1
pedantic: ^1.11.0
test: ^1.17.4

View file

@ -18,10 +18,8 @@ void main() {
setUp(() async {
app = Angel();
http = AngelHttp(app, useZone: false);
var auth = AngelAuth();
auth.serializer = (_) async => 'baz';
auth.deserializer = (_) async => USER;
var auth = AngelAuth(
serializer: (_) async => 'baz', deserializer: (_) async => USER);
auth.strategies['local'] = LocalAuthStrategy(
(username, password) async {