创建热观察

时间:2015-06-04 14:00:24

标签: java rx-java

我正在接受RX的第一步。我已经阅读了一些有关它的内容,但我认为弄脏手是更好的方法。所以我开始将现有代码转换为Rx类型的代码。

目标: 我试图模拟一个发送具有特定频率(例如60 / s,摄像机或其他)的数据的源。我有录制的镜头来模拟源,而源不可用。我需要源才能开始发送,即使没有人在听,因为这就是真正的来源。

在Rx之前,我去制作了一个Runnable,它只是遍历15.000个数据项,将项目发送到我的RabbitMQ服务器并休眠1/60秒,然后发送下一个。

现在我想把这个逻辑变成一个热门的观察者,只是为了玩。到目前为止,我有这个:

Observable.from(mDataItems)
                .takeWhile(item -> mRunning)
                .map(mGson::toJson)
                .doOnNext(json -> {
                    try {
                        mChannel.basicPublish(EXCHANGE_NAME, "", null, json.getBytes());
                    } catch (IOException e) {
                        Logger.error(e, String.format("Could not publish to %s exchange", EXCHANGE_NAME));
                    }

                    try {
                        Thread.sleep(1 / SENDING_FREQUENCY_IN_HZ);
                    } catch (InterruptedException e) {
                        Logger.error(e, String.format("Could not sleep for %d ms", (int) (1000 / SENDING_FREQUENCY_IN_HZ)));
                    }
                })
                .doOnCompleted(() -> {
                    if (mRunning)
                        Logger.info("All data sent");
                    else
                        Logger.info("Interrupted while sending");

                    disconnect();
                    mRunning = false;
                })
                .subscribeOn(Schedulers.io())
                .publish()
                .connect(); 

即使它到目前为止工作,我也不知道这是否是“好”的方式来创建一个只发出项目的热Observable(或一般的Observable)。 (我也不知道我是否应该使用Subject而不是Observable,但那是另一个问题。)

1 个答案:

答案 0 :(得分:1)

是的,还有另一种选择:

int delay = 1000 / frequency;
Observable o = Observable.from(dataItems)
.zipWith(
    Observable.timer(delay, delay, TimeUnit.MILLISECONDS)
        .onBackpressureDrop(),
    (s, t) -> s)
.map(mGson::toJson)
// other ops as necessary
.subscribeOn(Schedulers.io())
.publish();

o.connect();

o.subscribe(...);