Подпишитесь на поток событий с сервера

Я подробно рассказываю о примере redux-observable для пинг-понга, и моя конечная цель - отправлять действие при каждом полученном с сервера событии.

Но у меня возникли некоторые проблемы с пониманием того, как на самом деле этого добиться.

Что у меня есть на данный момент:

1. При открытии соединения мой сервер начинает отправлять сообщения.

// server.js
setInterval(()=>{
    ws.send(JSON.stringify({
        type: 'INCREMENT',
        status: 200
    }))
    console.log("sent some data")
},3000)

2. На клиенте я установил Observable для этого соединения с Websocket.

const socket$ = Observable.webSocket("ws://localhost:8081")

Остальная часть кода похожа на пример JSBin для реакции

Как сформировать эпос для этой задачи? Как отправить действие?


person n3u3w3lt    schedule 11.08.2017    source источник
comment
github.com/Reactive-Extensions/RxJS/issues/112   -  person eenagy    schedule 12.08.2017
comment
@eenagy, это rxjs v4, кстати, и неточно для v5   -  person jayphelps    schedule 12.08.2017
comment
Привет @ n3u3w3, непонятно о чем спрашиваешь. Не могли бы вы исправить?   -  person jayphelps    schedule 12.08.2017
comment
@jayphelps, конечно. По сути, мне нужно, чтобы мое приложение выполняло следующие действия: 1. Откройте приложение, которое подключается к серверу через веб-сокет, приложение создает наблюдаемое соединение этого веб-сокета. 2. Сервер отправляет бесконечное количество сообщений INCREMENT любому подключенному пользователю. 3. При получении каждого сообщения должно быть отправлено действие. Итак, если мой state.counter был равен нулю, после получения события он должен стать 1,2,3 и т.д.   -  person n3u3w3lt    schedule 12.08.2017
comment
Вы пытались создать эпос, используя свои знания Rx и документы: redux- observable.js.org/docs/basics/Epics.html? Не могли бы вы добавить это к своему ответу?   -  person jayphelps    schedule 12.08.2017
comment
В этом примере я представляю, что моя эпопея должна быть примерно такой const incrementEpic = action$ => action$.ofType('NCREMENT_INTENT) // intent to change the state .mapTo({type: 'INCREMENT_APPLY'}) // dispatching an action Вопрос в том, где мне разместить прослушивание логики событий веб-сокета?   -  person n3u3w3lt    schedule 12.08.2017
comment
Можете ли вы описать, как веб-сокет взаимодействует с этой эпопеей? Через розетку надо что-то пересылать? Получить вещи обратно? Только слушать с сервера? Вам нужно мультиплексирование или только один канал?   -  person jayphelps    schedule 13.08.2017
comment
Извините за все вопросы :) много требований, прежде чем я смогу эффективно предлагать решения   -  person jayphelps    schedule 13.08.2017
comment
@jayphelps, мне просто нужно установить соединение при запуске моего клиентского приложения и получать только фиктивные сообщения от веб-сокета. Сервер бесконечно присылает мне пинги. У меня есть хранилище redux, которое выглядит как {counter:0}, и я хочу увеличивать этот coutner при каждом полученном событии. Это одноканальный, и он максимально простой :)   -  person n3u3w3lt    schedule 13.08.2017


Ответы (1)


Мы немного обсудили это в комментариях, но, боюсь, я до сих пор не совсем понимаю, как инкремент / счетчик / INCREMENT_APPLY относится к сокету, но я могу дать вам простой пример:

const somethingEpic = action$ =>
  action$.ofType('START_SOCKET_OR_WHATEVER')
    .switchMap(action =>
      Observable.webSocket('ws://localhost:8081')
        .map(response => ({ type: 'RECEIVED_MESSAGE', paylod: response }))
    );

Здесь, когда отправлено START_SOCKET_OR_WHATEVER, мы начнем прослушивать наш сокет. Каждый раз, когда сообщение получено, мы сопоставляем его с RECEIVED_MESSAGE действием, которое будет отправлено после того, как epic отправит его.

Вы заметите, что это почти идентично тому, как вы бы сделали одиночный ajax. Только если вам нужно отправлять сообщения на сервер или мультиплекс, он будет заметно отличаться.

person jayphelps    schedule 13.08.2017
comment
Большое спасибо, @jayphelps, это именно то поведение, которое я искал. Я проверил это только сейчас, и он работает как задумано - я открываю соединение, отправляя действие SOCKET_START, и после отправки действия мое приложение начинает получать пинги с сервера и увеличивает значение счетчика - person n3u3w3lt; 14.08.2017
comment
уууу! так рад! - person jayphelps; 15.08.2017
comment
@jayphelps Я не думаю, что вы могли бы дополнительно указать мне в правильном направлении, чтобы также прослушивать события сбоя / закрытия сокета? например, { type: 'SOCKET_CLOSED' } - person Josh Mc; 26.08.2019
comment
Тема @JoshMc webSocket будет подписчиками complete () или error () в зависимости от того, было ли это чистое закрытие. Вы также можете предоставить closeObserver. Если вам нужна более конкретная помощь, например, как превратить это в действие redux, которое вы испускаете, вероятно, лучше всего создать новый вопрос stackoverflow, описывающий ваши потребности. Надеюсь это поможет! - person jayphelps; 26.08.2019