React 客户端无法正确分发接收到的 ActionCable 广播

React client has trouble properly distributing received ActionCable broadcast

在这两种浏览器上,我的聊天应用程序都按预期运行 2-3 轮消息。之后,我在 Safari 上多次出现相同的消息,但在 Chrome 我的问题是消息完全停止。


更新:

自从最初发布我的问题后,我尝试以相反的顺序登录 Safari 和 Chrome。当我这样做时,问题实际上发生了变化。在控制台中,我看到无论哪个浏览器第二个登录到聊天室,都会收到 2 个或更多广播实例,而第一个登录的用户将不会收到任何消息。


我最初在接收广播时遇到了问题,但通过使用 npm 包 react-actioncable-provider 解决了这个问题。我的问题和答案可以在这里找到:

我已经将 cable.yml 适配器设置为 redis、postgresql 和异步进行了测试。正如预期的那样,异步根本不起作用。无论我使用 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

这是我使用 redux 编写的客户端代码:

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 的广播数据时,我的 reducer 被调用 action.type "UP_MSG"。在那个开关盒内,我有一个 console.log 并且可以在 Chrome 和 Safari 中看到,不仅没有显示消息,而且在一段时间后没有收到消息的时间。在接收多条消息的浏览器上,我可以看到我的 "UP_MSG" 案例中的 console.log 在我的 reducer 中出现的次数与消息出现的次数一样多。

我没有看到终端的后端输出有任何不同。因为该行为是相同的,并且因为两个浏览器都有不同的错误,所以我认为问题一定出在客户端上。

即使您没有答案,任何有关调试的有用想法也将不胜感激。感谢您阅读到这里!

虽然起初我相当确定这是一个前端问题,但事实证明我错了。当我离开我的笔记本电脑一分钟时,我首先意识到这可能是一个性能问题,并发现所有消息确实都传输到 "silent" 浏览器 window,只是发生得很慢.

搜索我的后端代码,我找不到任何特别会降低性能的东西。特别是当我在一个只有一个群聊室的演示分支中工作时,不需要整理属于哪里。

搜索时,我找到了这篇文章:https://evilmartians.com/chronicles/anycable-actioncable-on-steroids

这让我找到了 github 上的 anycable-rails 的文档:https://github.com/anycable/anycable-rails

在我的 MacBook Air 上通过 brew 安装 anycable-go,然后按照 anycable-rails 文档中提供的步骤将 gem 添加到我的 rails 后端对我有用.

一旦我配置并安装了 anycable-rails,我的应用程序就不再有问题了。