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

时间:2019-03-23 16:21:18

标签: ruby-on-rails reactjs redux react-redux actioncable

在两个浏览器上,我的聊天应用程序都可以正常工作2-3次消息传递。之后,我得到的同一条消息在Safari上出现了很多次,但是在Chrome上,我的问题是消息完全停止了。


更新:

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


最初,我根本无法接收到广播,但是使用npm包react-actioncable-provider解决了它。我的问题和答案可以在这里找到:Cannot access data from ActionCable on 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

这是我使用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接收广播的数据时,发生的事情是用action.type“ UP_MSG”调用了我的reducer。在该开关盒的内部,我有一个console.log,并且可以在Chrome和Safari中看到,不仅不显示消息,而且在一定时间后也没有接收到消息。在接收多条消息的浏览器上,我可以看到减速器中“ UP_MSG”案例中的console.log出现的次数与消息出现的次数相同。

我看不到终端的后端输出有什么区别。因为该行为是相同的,并且由于两个浏览器都有不同的错误,所以我认为问题必须出在客户端上。

即使您没有答案,对调试的任何有益思考也将不胜感激。感谢您阅读本文!

1 个答案:

答案 0 :(得分:0)

尽管起初我相当确定这是一个前端问题,但事实证明我弄错了。我最初有一个线索,当我离开笔记本电脑一分钟时,这可能是性能问题,并且发现所有消息确实都传输到了“静默”浏览器窗口中,只是发生得很慢。

在搜索我的后端代码时,我找不到任何特别会降低性能的东西。尤其是当我在演示分支中工作时,只有一个小组聊天室,而无需对所属内容进行排序。

在搜索时,我发现了这篇文章: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,我的应用就不再有问题。