【问题标题】:Rails 5 ActionCable issue with running multiple channels for a web socketRails 5 ActionCable 问题,为 Web 套接字运行多个通道
【发布时间】:2016-05-24 17:33:24
【问题描述】:

snlamm 我在 Rails 应用程序中实现多个 Web 套接字通道时遇到问题。错误是服务器在以下响应后冻结:

Started GET "/cable" for ::1 at 2016-05-24 11:42:16 -0400
Started GET "/cable/" [WebSocket] for ::1 at 2016-05-24 11:42:16 -0400
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)

注意:我们的浏览器控制台不会抛出任何错误。我们使用的是 Chrome v 50.0(最新版本)。

但是,如果我们重新启动浏览器和服务器,则会出现不一致的情况:

Started GET "/cable" for ::1 at 2016-05-24 11:45:54 -0400
Started GET "/cable/" [WebSocket] for ::1 at 2016-05-24 11:45:54 -0400
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
ItemsChannel is transmitting the subscription confirmation
ItemsChannel is streaming from items
MessagesChannel is transmitting the subscription confirmation
MessagesChannel is streaming from messages

一切正常。

如前所述,此修复程序不一致,而且我们的服务器经常死机。我们注意到,当我们只运行一个频道时不会出现任何问题。

这是我们添加的两个通道之一的 items 通道的代码。两个频道的代码几乎相同:

路线

mount ActionCable.server => '/cable'

channels/application_cable/channel.rb

module ApplicationCable
  class Channel < ActionCable::Channel::Base
  end
end

channels/application_cable/connection.rb

module ApplicationCable
  class Connection < ActionCable::Connection::Base
  end
end

channels/items_channel.rb

class ItemsChannel < ApplicationCable::Channel
  def subscribed
    stream_from 'items'
  end
end

views/orders/show.html.erb

这是我们附加到显示项目的频道视图。

<div id="item-list">
      <h2>Items: <% @order.items.each do |item| %></h2>
      <li><%= item.name %> - $<%= item.cost %></li>
      <% end %>
    </div>
  </ol>
  <div id="item-errors">
  </div>
  <br>
  <h3>Time until ordered: <%= ((@order.expiration - @order.date_ordered) / 60).round %> minutes</h3></div>

  <%= form_for @item, remote: true do |f| %>
    <%= f.hidden_field :order_id, value: @order.id, id: "order-id" %>
  <span id='item-content-reset'>
    Item name: <%= f.text_field :name, id: 'item-name' %>
    Cost: <%= f.text_field :cost, id: 'item-cost' %>
  </span>
    <%= f.submit "Add Item", :id => 'item-create-btn' %>
  <% end %>
</div>

控制器/items_controller.rb

class ItemsController < ApplicationController
  def create
    @item = Item.new(item_params)
    @item.user = @current_user
    if @item.save
      ActionCable.server.broadcast 'items',
        name: @item.name,
        cost: @item.cost
      head :ok
    else
      error_message = @item.errors.messages
      render partial: 'shared/errors', locals: { errors: flash.now[:alert] = "Item " + error_message[:name][0] }
    end
  end

  private

  def item_params
    params.require(:item).permit(:order_id, :cost, :name)
  end
end

assets/application.js

//= require jquery
//= require bootstrap-sprockets
//= require jquery_ujs
//= require bootstrap-switch
// require jquery.session
// require turbolinks
//= require_tree .

assets/javascripts/channels/chatrooms.js

//= require action_cable
//= require_self
//= require_tree .

this.App = {};

App.cable = ActionCable.createConsumer("/cable");

assets/javascripts/channels/items.js

App.items = App.cable.subscriptions.create('ItemsChannel', {
  received: function(data) {
    return $("#item-list").append(this.renderItem(data));
  },
  renderItem: function(data) {
    return "<li> " + data.name + " - " + "$" + data.cost + "</li>";
  }
});

结束服务器后我们ps aux | grep 用于 rails、ruby、puma、redis,它们都已成功关闭(即没有僵尸进程)。什么可能导致服务器冻结?

【问题讨论】:

    标签: sockets ruby-on-rails-5 actioncable


    【解决方案1】:

    这听起来像以下错误 (Actioncable deadlock with multiple channels #24741)。您可以在前面的链接中获取补丁。如果您从事开发工作,也可以尝试在 development.rb 中设置 config.eager_load = true,这对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-19
      • 2021-09-29
      • 1970-01-01
      • 2017-01-04
      • 2017-07-31
      • 1970-01-01
      • 2019-11-22
      • 2017-05-15
      相关资源
      最近更新 更多