How to use RxJs with Socket.IO on event

后端 未结 6 906
温柔的废话
温柔的废话 2021-02-02 12:56

I want to use RxJS inside of my socket.on(\'sense\',function(data){});. I am stuck and confused with very few documentation available and my lack of understanding R

相关标签:
6条回答
  • 2021-02-02 13:18

    Simply use fromEvent(). Here is a full example in Node.js but works the same in browser. Note that i use first() and takeUntil() to prevent a memory leak: first() only listens to one event and then completes. Now use takeUntil() on all other socket-events you listen to so the observables complete on disconnect:

    const app = require('express')();
    const server = require('http').createServer(app);
    const io = require('socket.io')(server);
    const Rx = require('rxjs/Rx');
    
    connection$ = Rx.Observable.fromEvent(io, 'connection');
    
    connection$.subscribe(socket => {
        console.log(`Client connected`);
    
        // Observables
        const disconnect$ = Rx.Observable.fromEvent(socket, 'disconnect').first();
        const message$ = Rx.Observable.fromEvent(socket, 'message').takeUntil(disconnect$);
    
        // Subscriptions
        message$.subscribe(data => {
            console.log(`Got message from client with data: ${data}`);
            io.emit('message', data); // Emit to all clients
        });
    
        disconnect$.subscribe(() => {
            console.log(`Client disconnected`);
        })
    });
    
    server.listen(3000);
    
    0 讨论(0)
  • 2021-02-02 13:23

    I have experienced some strange issues using the fromEvent method, so I prefer just to create my own Observable:

    function RxfromIO (io, eventName) {
      return Rx.Observable.create(observer => {
        io.on(eventName, (data) => {
            observer.onNext(data)
        });
        return {
            dispose : io.close
        }
    });
    

    I can then use like this:

    let $connection = RxfromIO(io, 'connection');
    
    0 讨论(0)
  • 2021-02-02 13:24

    You can use Rx.Observable.fromEvent (https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/fromevent.md).

    Here's how I did a similar thing using Bacon.js, which has a very similar API: https://github.com/raimohanska/bacon-minsk-2015/blob/gh-pages/server.js#L13

    So in Bacon.js it would go like

    io.on('connection', function(socket){
      Bacon.fromEvent(socket, "sense")
        .filter(function(data) { return true })
        .forEach(function(data) { dealWith(data) })
    })
    

    And in RxJs you'd replace Bacon.fromEvent with Rx.Observable.fromEvent.

    0 讨论(0)
  • 2021-02-02 13:28

    You can use rxjs-dom,

    Rx.DOM.fromWebSocket(url, protocol, [openObserver], [closeObserver])
    
    
    // an observer for when the socket is open
    var openObserver = Rx.Observer.create(function(e) {
      console.info('socket open');
    
      // Now it is safe to send a message
      socket.onNext('test');
    });
    
    // an observer for when the socket is about to close
    var closingObserver = Rx.Observer.create(function() {
      console.log('socket is about to close');
    });
    
    // create a web socket subject
    socket = Rx.DOM.fromWebSocket(
      'ws://echo.websocket.org',
      null, // no protocol
      openObserver,
      closingObserver);
    
    // subscribing creates the underlying socket and will emit a stream of incoming
    // message events
    socket.subscribe(
      function(e) {
        console.log('message: %s', e.data);
      },
      function(e) {
        // errors and "unclean" closes land here
        console.error('error: %s', e);
      },
      function() {
        // the socket has been closed
        console.info('socket closed');
      }
    );
    
    0 讨论(0)
  • 2021-02-02 13:35

    You can create an Observable like so:

    var senses = Rx.Observable.fromEventPattern(
        function add (h) {
          socket.on('sense',h);
        }
      );
    

    Then use senses like any other Observable.

    0 讨论(0)
  • 2021-02-02 13:43

    ES6 one liner that i use, using ES7 bind syntax:
    (read $ as stream)

    import { Observable } from 'rxjs'
    
    // create socket
    
    const message$ = Observable.create($ => socket.on('message', ::$.next))
    // translates to: Observable.create($ => socket.on('message', $.next.bind(this)))
    
    // filter example
    const subscription = message$
      .filter(message => message.text !== 'spam')
      //or .filter(({ text }) => text !== 'spam')
      .subscribe(::console.log)
    
    0 讨论(0)
提交回复
热议问题