Как получать данные в канале ActionCable без JS?

Я пишу приложение Rails, которое использует WebSockets для связи с другими машинами (в этом процессе нет логики на стороне браузера и клиента). У меня есть канал:

class MachinesChannel < ApplicationCable::Channel
  def subscribed
    ...
  end

  def unsubscribed
    ...
  end

  def handle_messages
    ...
  end
end

Единственный способ получить данные, о котором я знаю, - это клиент JavaScript:

ActionCable.createConsumer('/cable').subscriptions.create 'MachinesChannel',
  received: (message) ->
    @perform('handle_messages')

Я могу вызывать методы на стороне сервера из JS через метод @perform().

Есть ли способ опустить часть JS и как-то напрямую обрабатывать входящие данные в MachinesChannel?

Идеальной ситуацией было бы, чтобы метод handle_messages принимал аргумент data и вызывал этот метод для входящих данных.


person pmichna    schedule 06.04.2016    source источник


Ответы (2)


Изучив исходный код ActionCable, я получил следующее решение. Вам просто нужно создать метод в MachinesChannel, который вы хотите вызывать, например. handle_messages(data). Затем в клиенте, который подключается к вашему вебсокету, вам нужно отправить сообщение в следующем формате (пример на ruby):

id = { channel: 'MachinesChannel' }
ws = WebSocket::Client::Simple.connect(url)
ws.send(JSON.generate(command: 'message', identifier: JSON.generate(id), data: JSON.generate(action: 'handle_messages', foo: 'bar', biz: 'baz')))

action должно быть именем метода, который вы хотите вызвать в MachinesChannel. Остальные ключи-значения - все, что вы хотите. Эту дату вы можете получить в канале ActionCable.

Недавно был выпущен гем action_cable_client, который идеально подходит для такого использования. Я им не пользовался, поэтому не знаю, как он на самом деле работает.

person pmichna    schedule 12.04.2016
comment
Привет! action_cable_client — моя жемчужина. Если у кого-то есть вопросы по использованию, буду рад помочь! :-) - person NullVoxPopuli; 16.04.2016

Вместо:

def handle_messages
 ...
end

Это работает для меня:

def receive(data)
  puts data
  ...
end
person Gundam Meister    schedule 03.05.2018