How to buffer stream using fromWebSocket Subject

时间秒杀一切 提交于 2019-12-06 10:42:52

问题


This RxJava buffer example (with marble chart!) describes the desired result perfectly:

collect items in buffers during the bursty periods and emit them at the end of each burst, by using the debounce operator to emit a buffer closing indicator to the buffer operator

Edit: having reviewed How to create a RxJS buffer that groups elements in NodeJS but that does not rely on forever running interval?, my issue appears related to using a Subject as opposed to straight Observable.

Using the socket stream to generate window close events (as follows) results in 2 sockets opened and no events streaming out:

ws = Rx.DOM.fromWebSocket(wsURI, null, wsOpenObserver, wsCloseObserver);
var closer = ws.flatMapFirst(Rx.Observable.timer(250));
ws.buffer(closer)
    .subscribe(function(e) { console.log(e, 'socket messages');});

回答1:


Summarizing the findings issue here :

  • Rx.DOM.fromWebSocket returns a Rx.subject which wraps around the websocket. That subject is made from one observer and one observable (via new Rx.Subject(observer, observable). From what I understood, that observer allows to write to the socket via its onNext method, while the observable allows to read from the socket.
  • you always read that subjects are hot sources, but apparently here that only means that the observer will immediately push its value to the subject which here pushes it to the socket. In normal cases(new Rx.Subject()), the default observer and observable are so that the observable listens to the observer, hence the default observable is hot. Here however, the observable is a cold source and then any subscription will reexecute the callback creating another websocket. Hence the creation of two sockets.
  • this does not happen for instance with Rx.dom.fromEvent because the created (cold) observable is shared (via publish().refCount()).
  • thus by doing the same here, the duplication issue can be solved. That means in this particular case, use in your code ws = Rx.DOM.fromWebSocket(wsURI, null, wsOpenObserver, wsCloseObserver).share();, share being an alias for publish().refCount().
  • I have to wonder whether that behaviour of Rx.DOM.fromWebSocket should be reported as a bug

Code for both methods:

  • https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/src/dom/websocket.js
  • https://github.com/Reactive-Extensions/RxJS-DOM/blob/master/src/events/fromevent.js



回答2:


You can pass an Observable directly to the buffer operator just like the RxJava version:

source.buffer(source.debounce(150))

is valid. See here.

The alternative syntax using the selector method that you show will invoke that method every time a buffer closes and then subscribe to the Observable it produces.

Also the debounce in the RxJava example is emitting the result of the buffer operator, it does not emit accumulated results by default.



来源:https://stackoverflow.com/questions/33495390/how-to-buffer-stream-using-fromwebsocket-subject

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!