web-dev-qa-db-fra.com

Comment utiliser les RxJ avec Socket.IO sur un événement

Je veux utiliser RxJS dans mon socket.on('sense',function(data){});. Je suis coincé et confus avec très peu de documentation disponible et mon manque de compréhension de RxJS. Voici mon problème. 

J'ai un distSensor.js qui a une fonction pingEnd () 

function pingEnd(x){
socket.emit("sense", dist); //pingEnd is fired when an Interrupt is generated.
}

Dans mon App.js j'ai

io.on('connection', function (socket) {
    socket.on('sense', function (data) {
        //console.log('sense from App4 was called ' + data);
    });
});

La fonction de détection récupère de nombreuses données de capteur que je souhaite filtrer à l'aide de RxJS et je ne sais pas comment procéder pour utiliser les RxJ ici. Tout pointeur vers la documentation ou un échantillon correct serait utile. 

14
Mitul

Je pense que vous pouvez utiliser Rx.Observable.fromEvent ( https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/fromevent.md ).

Voici comment j'ai fait une chose similaire en utilisant Bacon.js, qui a une API très similaire: https://github.com/raimohanska/bacon-minsk-2015/blob/gh-pages/server.js#L13

Donc dans Bacon.js ça irait comme

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

Et dans RxJs, vous devriez remplacer Bacon.fromEvent par Rx.Observable.fromEvent.

14
raimohanska

J'ai rencontré des problèmes étranges avec la méthode fromEvent. Je préfère donc créer mon propre observable:

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

Je peux alors utiliser comme ceci:

let $connection = RxfromIO(io, 'connection');
16
Morten Poulsen

Vous pouvez créer un observable comme ceci:

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

Utilisez ensuite senses comme n’importe quel autre observable.

9
Xesued

ES6 un liner que j'utilise, en utilisant ES7 bind syntax:
(lire $ comme 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)
1
woudsma

Utilisez simplement fromEvent(). Voici un exemple complet dans Node.js mais fonctionne de la même manière dans le navigateur. Notez que j’utilise first() et takeUntil() pour éviter une fuite de mémoire: first() n’écoute qu’un événement, puis se termine. Maintenant, utilisez takeUntil() sur tous les autres événements de socket que vous écoutez afin que les observables se terminent lors de la déconnexion:

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);
1
Mick

Vous pouvez utiliser 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
serkan