Клиент React не может правильно распределить полученную трансляцию ActionCable - PullRequest
1 голос
/ 23 марта 2019

В обоих браузерах мое приложение чата работает ожидаемым образом в течение 2-3 раундов обмена сообщениями. После этого я получаю одно и то же сообщение много раз в Safari, но в Chrome моя проблема заключается в том, что обмен сообщениями полностью прекращается.


UPDATE:

С момента публикации моего вопроса я попытался войти в Safari и Chrome в обратном порядке. Когда я делаю это, проблема на самом деле переключается. В консоли я вижу, что любой браузер, вошедший в чат-секцию, получит 2 или более экземпляров широковещательной рассылки, а пользователь, вошедший в систему первым, не получит сообщений.


У меня изначально были проблемы с получением широковещательной рассылки, но я решил ее с помощью пакета response-actioncable-provider пакета npm. Мой вопрос и ответ на него можно найти здесь: Невозможно получить доступ к данным из ActionCable на React front-end

Я проверил с моим адаптером cable.yml, установленным на redis, postgresql и async. Как и ожидалось, асинхронный не работает вообще. Та же проблема возникает, использую ли я redis или postgresql в качестве адаптера.

Я занимаюсь разработкой и тестированием на MacBook Air. Моя версия ruby ​​- 2.6.2, а версия rails - 5.2.2.

Вот мой messages_channel.rb:

class MessagesChannel < ApplicationCable::Channel
  def subscribed
    @game = Game.find(params[:game_id])
    stream_for @game
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end
end

Это функция создания в моем messages_controller.rb:

  def create
    @game = Game.find(message_params[:game_id])
    @message = Message.new(message_params)
    if @message.save
      serialized_data = ActiveModelSerializers::Adapter::Json.new(
        MessageSerializer.new(@message)
      ).serializable_hash
      puts "serialized_data"
      MessagesChannel.broadcast_to @game, serialized_data
    end
  end

Вот мой код на стороне клиента, написанный в реакции с использованием приставки:

import { ActionCable } from 'react-actioncable-provider';
import React, { Component, Fragment } from 'react';
import { connect } from 'react-redux';


class Cable extends Component {

  render () {
    return (
      <Fragment>
        <ActionCable
          key={this.props.game_id}
          channel={{ channel: "MessagesChannel", game_id: this.props.game_id }}
          onReceived={(data) => {
            console.log("MessagesChannel recvd data: ",data)
            this.props.getMessages(data.message)
          }}
        />
    </Fragment>
    )
  }
}

const mapStateToProps = state => {
  return { state }
}

const mapDispatchToProps = dispatch => {
  return {
    getMessages: data => dispatch({ type: "UP_MSG", payload: data })
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Cable);

Что происходит, когда мой клиент успешно получает широковещательные данные из actioncable, так это то, что мой редуктор вызывается с action.type "UP_MSG". В этом случае у меня есть файл console.log, и я вижу в Chrome & Safari, что не только сообщения не отображаются, но и сообщения не принимаются через определенный промежуток времени. В браузере, получающем несколько сообщений, я вижу, что console.log изнутри моего корпуса "UP_MSG" в моем редукторе отображается столько раз, сколько появляется сообщение.

Я не вижу никакой разницы в выходных данных бэкэнда в терминале. Поскольку это поведение одинаково и оба браузера имеют разные ошибки, я думаю, что проблема должна быть на клиенте.

Даже если у вас нет ответа, любые полезные мысли по отладке будут с благодарностью. Спасибо за чтение этого далеко!

1 Ответ

0 голосов
/ 24 марта 2019

Хотя сначала я был совершенно уверен, что это проблема внешнего интерфейса, оказалось, что я ошибся. Сначала я понял, что это может быть проблема с производительностью, когда я на минуту отошел от своего ноутбука, и обнаружил, что все сообщения действительно передаются в «тихое» окно браузера, это происходило довольно медленно.

Просматривая свой бэкэнд-код, я не смог найти ничего, что могло бы сильно снизить производительность. Тем более, что я работаю в демо-ветке, где есть только один групповой чат, и мне не нужно разбираться, где что находится.

При поиске я нашел эту статью: https://evilmartians.com/chronicles/anycable-actioncable-on-steroids

Это привело меня к документации по anycable-рельсам на github: https://github.com/anycable/anycable-rails

Установка anycable-go через brew на моем MacBook Air, затем следуя инструкциям, приведенным в документах anycable-rails, чтобы добавить драгоценный камень в мой рельс, сработал для меня.

Как только я настроил и установил anycable-rails, у меня перестали возникать проблемы с моим приложением.

...