Как использовать RxJs с Socket.IO на мероприятии

Я хочу использовать RxJS внутри моего socket.on('sense',function(data){});. Я застрял и запутался с очень небольшим количеством доступных документов и отсутствием понимания RxJS. Вот моя проблема.

У меня есть distSensor.js, который имеет функцию pingEnd()

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

Внутри моего App.js у меня

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

Функция чувств получает множество данных датчиков, которые я хочу фильтровать с помощью RxJS, и я не знаю, что мне делать, чтобы использовать RxJs здесь. Любые указатели на правильные документы или образец помогут.

Ответ 1

Я думаю, вы можете использовать Rx.Observable.fromEvent (https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/fromevent.md).

Вот как я сделал аналогичную вещь, используя Bacon.js, которая имеет очень похожий API: https://github.com/raimohanska/bacon-minsk-2015/blob/gh-pages/server.js#L13

Итак, в Bacon.js это будет похоже на

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

И в RxJs вы замените Bacon.fromEvent на Rx.Observable.fromEvent.

Ответ 2

У меня возникли некоторые странные проблемы с использованием метода fromEvent, поэтому я предпочитаю просто создать свой собственный Observable:

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

Затем я могу использовать вот так:

let $connection = RxfromIO(io, 'connection');

Ответ 3

Вы можете создать Observable следующим образом:

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

Затем используйте senses, как и любое другое Наблюдаемое.

Ответ 4

ES6 один вкладыш, который я использую, используя привязка ES7: (читайте $ как 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)

Ответ 5

Вы можете использовать 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');
  }
);

Ответ 6

Просто используйте fromEvent(). Вот полный пример в Node.js, но он работает в браузере. Обратите внимание, что я использую first() и takeUntil() для предотвращения утечки памяти: first() только прослушивает одно событие, а затем завершает. Теперь используйте takeUntil() для всех других событий сокета, которые вы слушаете, чтобы наблюдаемые были завершены при отключении:

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