IsolateChannel< T>.connectReceive constructor
Connects to a remote channel that was created with IsolateChannel.connectSend.
These constructors establish a connection using only a single SendPort/ReceivePort pair, as long as each side uses one of the connect constructors.
The connection protocol is guaranteed to remain compatible across versions at least until the next major version release. If the protocol is violated, the resulting channel will emit a single value on its stream and then close.
Implementation
factory IsolateChannel.connectReceive(ReceivePort receivePort) {
// We can't use a [StreamChannelCompleter] here because we need the return
// value to be an [IsolateChannel].
var streamCompleter = new StreamCompleter<T>();
var sinkCompleter = new StreamSinkCompleter<T>();
var channel =
new IsolateChannel<T>._(streamCompleter.stream, sinkCompleter.sink);
// The first message across the ReceivePort should be a SendPort pointing to
// the remote end. If it's not, we'll make the stream emit an error
// complaining.
StreamSubscription<dynamic> subscription;
subscription = receivePort.listen((message) {
if (message is SendPort) {
var controller = new StreamChannelController<T>(
allowForeignErrors: false, sync: true);
new SubscriptionStream(subscription)
.cast<T>()
.pipe(controller.local.sink);
controller.local.stream
.listen((data) => message.send(data), onDone: receivePort.close);
streamCompleter.setSourceStream(controller.foreign.stream);
sinkCompleter.setDestinationSink(controller.foreign.sink);
return;
}
streamCompleter.setError(
new StateError('Unexpected Isolate response "$message".'),
StackTrace.current);
sinkCompleter.setDestinationSink(new NullStreamSink<T>());
subscription.cancel();
});
return channel;
}