如何制作我自己的Stream

时间:2014-04-30 19:44:51

标签: stream dart

我已经尝试了解API文档,有关它们的文章以及此帖子:How do you create a Stream in Dart

我正在使用WebSocket创建一个简单的Web应用程序。实际上,它运作良好,但我想添加一个功能(享受学习)。

这是我的课(我猜可以优化)

library Ask;

import 'dart:html';
import 'dart:async';
import 'dart:convert';

class Ask {
    final String addr;
    String _protocol;
    String _port;
    WebSocket _ws;
    bool openned;
    Map<int, Completer> _completer_list = {};
    int _counter = 0;
    static final Map<String, Ask> _cache = <String, Ask>{};

    factory Ask(String addr) {
        if (_cache.containsKey(addr)) {
            return _cache[addr];
        } else {
            final ask_server = new Ask._internal(addr);
            _cache[addr] = ask_server;
            return ask_server;
        }
    }

    Ask._internal(this.addr);

    Future<bool> open() {
        if (openned)
            return true;
        _completer_list[0] = new Completer();
        if (window.location.protocol == 'http:') {
            _port = ':8080/ws';
            _protocol = 'ws://';
        } else {
            _port = ':8443/ws';
            _protocol = 'wss://';
        }
        _ws = new WebSocket(_protocol + addr + _port);
        _ws.onOpen.listen((e) {
            _get_data();
            _get_close();
            openned = true;
            _completer_list[0].complete(true);
        });
        return _completer_list[0].future;
    }

    Future<String> send(Map data) {
        bool check = false;
        int id;

        _completer_list.forEach((k, v) {
            if (v.isCompleted) {
                id = data['ws_id'] = k;
                _completer_list[k] = new Completer();
                _ws.send(JSON.encode(data));
                check = true;
            }
        });
        if (!check) {
            _counter++;
            id = data['ws_id'] = _counter;
            _completer_list[id] = new Completer();
            _ws.send(JSON.encode(data));
        }
        return _completer_list[id].future;
    }

    void _get_data() {
        _ws.onMessage.listen((MessageEvent data) {
            var response = JSON.decode(data.data);
            _completer_list[response['ws_id']].complete(response);
        });
    }

    void _get_close() {
        _ws.onClose.listen((_) {
            print('Server have been lost. Try to reconnect in 3 seconds.');
            new Timer(new Duration(seconds: 3), () {
                _ws = new WebSocket(_protocol + addr + _port);
                _get_data();
                _get_close();
                _ws.onOpen.listen((e) => print('Server is alive again.'));
            });
        });
    }
}

使用示例:

void showIndex() {
    Element main = querySelector('main');
    Ask connect = new Ask('127.0.0.1');
    Map request = {};

    request['index'] = true;
    connect.open().then((_) {
        connect.send(request).then((data) {
            main.setInnerHtml(data['response']);
        });
    });
}

我会将then替换为listen,当邮件完成时,{{1}}将被取消。通过这种方式,我可以添加一个进度条,我想......

所以我的问题是,我的发送功能可以是一个流,并保留我的概念为所有人的一个websocket? (是的,如果我的功能在请求正在进行时使用,它会被发送,如果她在第一次之前完成,我就会正确地恢复她。谢谢ws_id)。

谢谢。

1 个答案:

答案 0 :(得分:2)