В обоих браузерах мое приложение чата работает ожидаемым образом в течение 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" в моем редукторе отображается столько раз, сколько появляется сообщение.
Я не вижу никакой разницы в выходных данных бэкэнда в терминале. Поскольку это поведение одинаково и оба браузера имеют разные ошибки, я думаю, что проблема должна быть на клиенте.
Даже если у вас нет ответа, любые полезные мысли по отладке будут с благодарностью. Спасибо за чтение этого далеко!