2018-02-14 09:58:31 +00:00
|
|
|
import 'dart:async';
|
|
|
|
import 'package:angel_framework/angel_framework.dart';
|
|
|
|
import 'package:angel_websocket/server.dart';
|
|
|
|
import 'package:eventsource/eventsource.dart';
|
|
|
|
import 'package:eventsource/src/encoder.dart';
|
|
|
|
import 'package:eventsource/publisher.dart';
|
2018-11-08 15:09:32 +00:00
|
|
|
import 'package:stream_channel/stream_channel.dart';
|
2018-02-14 09:58:31 +00:00
|
|
|
|
|
|
|
class AngelEventSourcePublisher {
|
2018-11-08 15:09:32 +00:00
|
|
|
final AngelWebSocket webSocketDriver;
|
2018-02-14 09:58:31 +00:00
|
|
|
|
2018-11-08 15:09:32 +00:00
|
|
|
final String channel;
|
2018-02-14 09:58:31 +00:00
|
|
|
|
|
|
|
int _count = 0;
|
|
|
|
|
2018-11-08 15:09:32 +00:00
|
|
|
AngelEventSourcePublisher(this.webSocketDriver, {this.channel: ''});
|
2018-02-14 09:58:31 +00:00
|
|
|
|
2018-11-08 15:09:32 +00:00
|
|
|
Future handleRequest(RequestContext req, ResponseContext res) async {
|
2018-02-14 09:58:31 +00:00
|
|
|
if (!req.accepts('text/event-stream', strict: false))
|
|
|
|
throw new AngelHttpException.badRequest();
|
|
|
|
|
2018-11-08 15:09:32 +00:00
|
|
|
res.headers.addAll({
|
|
|
|
'cache-control': 'no-cache, no-store, must-revalidate',
|
|
|
|
'content-type': 'text/event-stream',
|
|
|
|
'connection': 'keep-alive',
|
|
|
|
});
|
2018-02-14 09:58:31 +00:00
|
|
|
|
|
|
|
var acceptsGzip =
|
|
|
|
(req.headers['accept-encoding']?.contains('gzip') == true);
|
|
|
|
|
2018-11-08 15:09:32 +00:00
|
|
|
if (acceptsGzip) res.headers['content-encoding'] = 'gzip';
|
2018-02-14 09:58:31 +00:00
|
|
|
|
|
|
|
var eventSink = new EventSourceEncoder(compressed: acceptsGzip)
|
2018-11-08 15:09:32 +00:00
|
|
|
.startChunkedConversion(res);
|
|
|
|
|
|
|
|
// Listen for events.
|
|
|
|
var ctrl = new StreamChannelController();
|
2018-02-14 09:58:31 +00:00
|
|
|
|
2018-11-08 15:09:32 +00:00
|
|
|
// Incoming events are strings, and should be sent via the eventSink.
|
|
|
|
ctrl.local.stream.cast<String>().listen((data) {
|
|
|
|
eventSink.add(new Event(
|
|
|
|
id: (_count++).toString(),
|
|
|
|
data: data,
|
|
|
|
));
|
|
|
|
});
|
2018-02-14 09:58:31 +00:00
|
|
|
|
2018-11-08 15:09:32 +00:00
|
|
|
// Create a new WebSocketContext, and hand it off to the driver.
|
|
|
|
var socket = new WebSocketContext(ctrl.foreign, req, res);
|
|
|
|
return await webSocketDriver.handleClient(socket);
|
2018-02-14 09:58:31 +00:00
|
|
|
}
|
|
|
|
}
|