loading...

Isolate at Flutter for Web

kyorohiro profile image kyorohiro (kiyohiro kawamura) Updated on ・2 min read

I explained a thread programming for wevdev and flutter for web in this document.

We could use isolate in Flutter to implement thread programming.
But, Flutter For Web is not support isolate now.

In this document, Use Worker instead of Isolate.

Dart's unsynchronized programming

Dart:isolate

We can use dart:isolate.

import 'dart:isolate' as iso;

Future main() async {
  iso.ReceivePort receivePort = iso.ReceivePort();
  iso.Isolate.spawn(workerMain, receivePort.sendPort);

  receivePort.listen((message) {
    print("host: ${message}");
  });
}

workerMain(sendPort) async { 
    for(var message in ["01","02","03"]) {
        (sendPort as iso.SendPort).send(message);
        await Future.delayed(Duration(seconds: 1));
    }
}

Worker for web

dart1 support dart:isolate, but darr2 not suport isoate for web now.
dart1 used worker to impolement isolate.
Let's use Worker, following Dart1 series dart:isolate.

parent.dart

import 'dart:html' as html;

main() async {
  if(html.Worker.supported) {
      var myWorker = new html.Worker("ww.dart.js");
      myWorker.onMessage.listen((event) {
        print("main:receive: ${event.data}");
      });
      myWorker.postMessage("Hello!!");
  } else {
    print('Your browser doesn\'t support web workers.');
  }
}

child.dart

import 'dart:async';
import 'dart:html' as html;

import 'dart:js' as js;
import 'package:js/js.dart' as pjs;
import 'package:js/js_util.dart' as js_util;

@pjs.JS('self')
external dynamic get globalScopeSelf;


Stream<T> callbackToStream<J, T>(String name, T Function(J jsValue) unwrapValue) {
  var controller = StreamController<T>.broadcast(sync: true);
  js_util.setProperty(js.context['self'], name, js.allowInterop((J event) {
    controller.add(unwrapValue(event));
  }));
  return controller.stream;
}

void jsSendMessage( dynamic object, dynamic m) {
  js.context.callMethod('postMessage',[m]);
}

main() {
    callbackToStream('onmessage', (html.MessageEvent e)  {
      return js_util.getProperty(e, 'data');
    }).listen((message) {
      print('>>> ${message}');
      jsSendMessage(js.context, 'callback: ${message}');
    });
}

PS

if send message parent to child at isoalte

import 'dart:isolate' as iso;
Future<int> main(List<String> args, iso.SendPort sendPoet) async {
  print("Start Main");
  iso.ReceivePort receivePort = iso.ReceivePort();
  receivePort.listen((message) {
    print("main:receive: ${message}");
    if(message is iso.SendPort) {
      (message as iso.SendPort).send("Hello!! Client");
    }
  });

  await iso.Isolate.spawnUri(new Uri.file("./child.dart"), [], receivePort.sendPort);

  return 0;
}

import 'dart:isolate' as iso;

int main(List<String> args, iso.SendPort sendPort) {
  print("Hello, World!!");
  sendPort.send("Start a child");
  iso.ReceivePort receivePort = iso.ReceivePort();
  receivePort.listen((message) {
    print("child: receive message: ${message}");
    sendPort.send(message);
  });
  sendPort.send(receivePort.sendPort);

  return 0;
}

dart2native restriction

iso.Isolate.spawnUri has a limitation at dart2native

Unsupported operation: Isolate.spawnUri is not supported when using AOT compilation

wevbdec ristriction

failed to build worker at webdev serve .

you must to build manually

dart2js web/xxx.dart -o web/xxx.dart.js

Code

https://github.com/kyorohiro/dart.tiny_worker

Next..

About common intreface for flutter and flutter for web and dart:io

Posted on by:

kyorohiro profile

kyorohiro (kiyohiro kawamura)

@kyorohiro

https://github.com/kyorohiro https://kyorohiro.gitbook.io/home/ https://twitter.com/kyorohiro/

Discussion

pic
Editor guide