将 ActionCable 连接到不同的主机

mat*_*att 4 ruby-on-rails ember.js actioncable

我正在运行一个 rails 5 应用程序作为后端服务器,以及一个用于前端应用程序的 ember 应用程序。它们是托管在两个不同域上的两个独立应用程序 - 例如,backend.devfrontend.dev

rails 应用程序有一个简单的连接类app/channels/application_cable/connection.rb,如下所示:

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    def connect
      Rails.logger.debug("env: #{env.inspect}")
      Rails.logger.info("cookies.signed: #{cookies.signed.inspect}")
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

我有一个简单的基本频道类,app/channels/application_cable/channel.rb如下所示:

module ApplicationCable
  class Channel < ActionCable::Channel::Base
  end
end
Run Code Online (Sandbox Code Playgroud)

以及该类的单个实现app/channels/events_channel.rb

class EventsChannel < ApplicationCable::Channel
  def subscribed
    Rails.logger.debug("env: #{env.inspect}")
    Rails.logger.info("cookies.signed: #{cookies.signed.inspect}")
    stream_from 'events'
  end
end
Run Code Online (Sandbox Code Playgroud)

在事情的余烬方面,我正在使用 ember-cable 包。我已经通过使用以下扩展控制器类在我的前端设置了我的使用者:

cableService: Ember.inject.service('cable'),

setupConsumer: Ember.on('init', function() {
  let service = this.get('cableService');
  let consumer = service.createConsumer(`ws://backend.dev`);
  let channel = 'EventsChannel';

  consumer.subscriptions.create(channel, {
    disconnected() {
      Ember.debug(`${channel}#disconnected`);
    },

    connected() {
      Ember.debug(`${channel}#connected`);
    },
Run Code Online (Sandbox Code Playgroud)

我相当确定我的使用者设置正确,因为当我将以下输出发送到我的 js 控制台时,我看到了一些调试输出:

DEBUG: EventsChannel#disconnected
Run Code Online (Sandbox Code Playgroud)

但是,我也在控制台中看到了一个奇怪的错误:

WebSocket connection to 'ws://backend.dev/' failed: Error during WebSocket handshake: Unexpected response code: 200
Run Code Online (Sandbox Code Playgroud)

我不知道如何处理这里的响应代码错误,而且我的 rails 应用程序中绝对没有记录任何内容。是否需要设置任何其他内容才能跨域进行可操作的工作?知道 200 响应代码在这里意味着什么吗?

Vik*_*tor 5

尝试这个:

# routes.rb
Rails.application.routes.draw do
  # your code
  mount ActionCable.server => '/cable'
end
Run Code Online (Sandbox Code Playgroud)

然后在您的应用中:

let consumer = service.createConsumer(`ws://backend.dev/cable`);
Run Code Online (Sandbox Code Playgroud)

如果您遇到握手问题,有几个解决方案:

  1. 检查您的前端应用程序是否兼容protocol 07或更新。

  2. 检查您的网站是否在 config.action_cable.allowed_request_origins

  3. 添加config.web_socket_server_url = 'ws://backend.dev/cable'到您的 ENV 配置文件中。

  4. 您可以使用快速的“脏” hack。只需将以下内容添加到您的 ENV 配置文件中:

    config.action_cable.disable_request_forgery_protection = true
    
    Run Code Online (Sandbox Code Playgroud)