Как именно настроить канал RoR для отправки данных туда и обратно - PullRequest
2 голосов
/ 19 февраля 2020

Я пытаюсь смоделировать грамматическую проверку орфографии с помощью ActionCable, но я немного пытаюсь понять, как

  • настроить аутентификацию
  • ретранслировать данные обратно и далее

Я прочитал много статей, включая официальные документы, и все же я чувствую растерянность. Итак, первое, что я сделал, это добавил в свой config/application.rb следующее:

    # Mount ActionCable.
    config.action_cable.mount_path = '/websocket'

Я также настроил аутентификацию:

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
    end

    private

    def find_verified_user
      current_user = User.find_by_api_key(token)
      if current_user
        current_user
      else
        reject_unauthorized_connection
      end
    end

    def token
      # TODO: verify if this is really safe.
      request.headers[:AUTHORIZATION].split('=').last
    end
  end
end

Я не использую device, и мой аутентификация основана на токене . У каждого пользователя есть фиксированный токен API, вот и все.

Надеюсь, что аутентификация правильная, я был бы признателен, если бы кто-то более опытный мог указать мне, если это не так.

Теперь я Мы создали канал с именем spell_checking_channel:

class SpellCheckingChannel < ApplicationCable::Channel
  def subscribed
    stream_from 'spell_checking_channel_' << current_user.id
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end
end

Как только я получу данные от внешнего интерфейса, я хотел бы позвонить на SpellChecker.call('text') и передать его обратно с результатами. Я знаю, это смешно, что я прошу помощи с этим, но я действительно не могу найти пример для этого. Кроме того, я должен сделать что-нибудь по unsubscribed методу?

1 Ответ

1 голос
/ 21 февраля 2020

ActionCable является оберткой вокруг WebSockets, при подключении к веб-сокету браузер передает те же файлы cookie, что и обычным запросам, поэтому работают разработанные и аналогичные методы аутентификации на основе cook ie. Для аутентификации на основе токена проще передать токен в следующих параметрах:

const my_token = '...';
const cable = ActionCable.createConsumer(`/websocket?token=${my_token}`);

при подключении он будет request.params[:token].

При отправке данных на канал js :

const channel = cable.subscriptions.create({ channel: "SpellCheckingChannel" }, {
  received(data) {
    // handle data from channel in some way
    console.log("received from rails:", data);
  }
});

channel.send({ some_data_to_rails: "goes_here" })

на бэкэнде:

class SpellCheckingChannel < ApplicationCable::Channel
  def subscribed
    # here we instruct ActionCable to send messages from following topic
    stream_from "spell_checking_channel_#{current_user.id}"
    # there may be multiple subscriptions in one channel:
    stream_from "spell_checking_channel_common"
  end

  def receive(data)
    # channel.send(data) ends up here

    ActionCable.server.broadcast("spell_checking_channel_#{current_user.id}", { this_goes_back: "to js" })

    if data[:foo] == "bar"
      ActionCable.server.broadcast("spell_checking_channel_common", { hey_listen_all: "lala" })
    end
  end
end

Основной трюк в том, что вы можете использовать ActionCable.server.broadcast в любом месте вашего приложения, не только в каналах, например - в канале вы можете поставьте в очередь фоновое задание, которое отправит свой результат на канал

...