Реализация чата Pusher в Rails

Поскольку актуальной информации о последних версиях Rails и Pusher не так много, как я могу реализовать Pusher в своем приложении Rails, чтобы получить чат между пользователями в реальном времени? В документации Pusher показано, как это сделать с Sinatra, но нет ничего конкретного для Rails...


person Tom Goldenberg    schedule 15.03.2015    source источник
comment
Взгляните на официальный гем https://github.com/pusher/pusher-http-ruby. для связи с пушером. Он обновлен и очень хорошо документирован.   -  person kobaltz    schedule 15.03.2015


Ответы (1)


Создайте файл инициализатора

приложение/config/initializers/pusher.rb

require 'pusher'

Pusher.url    = 'your-pusher-url'
Pusher.logger = Rails.logger

В вашем контроллере предположим, что это для сообщений чата:

приложение/контроллеры/messages_controller.rb

MessagesController < ApplicationController
  def create
    model = Message.create params_model
    json  = model.to_json
    channel = "private-conversation.#{params[:user_id]}"
    Pusher[channel].trigger 'messages/create', json
  end

  private
    def params_model
      params.require(:message).permit(:id,:body,:user_id)
    end
end

Авторизация

приложение/контроллеры/pusher_controller.rb

class PusherController < ApplicationController
  protect_from_forgery except: :auth_notify
  skip_before_filter :login_required, only: [:auth_notify]
  def auth
    channel    = params[:channel_name]
    socket_id  = params[:socket_id]

    valid = false
    valid = true if channel =~ /private-conversation\.(\d+)/

    if valid
      response = Pusher[channel].authenticate socket_id
      render json: response
    else
      render text: 'Not authorized', status: '403'
    end
  end
end

Маршруты:

маршруты.rb

YourApp::Application.routes.draw do
  resources :messages
  post '/pusher/auth'    => 'pusher#auth'
end

Где-то в вашем coffescript, скорее всего, в application.coffee, это предполагает, что у вас есть js-файл pusher cdn в вашем application.html.haml и jquery.

$->
    user_id = $('meta[name=user-id]').attr('user_id')
    key     = $('meta[name=pusher-key]').attr('content')
    csrf    = $('meta[name=csrf-token]').attr('content')
    @pusher = new Pusher key,
      auth:
        headers:
          'X-CSRF-Token': csrf
        params:
          user_id: user_id

обратите внимание, что вы должны добавить метатеги в свою голову, чтобы вы могли легко получить токен csrf, user_id и ключ pusher. Вам, конечно, нужен токен csrf, чтобы остановить спуфинг.

В вашем application.html.haml

!!! XML
!!! 5
%html
  %head
    = csrf_meta_tag
    = tag :meta, name: 'pusher-key', content: "#{current_user.id}"
    = tag :meta, name: 'pusher-key', content: 'pusher_public_key'
  %body
    = javascript_include_tag '//js.pusher.com/2.2/pusher.min.js'
    = javascript_include_tag :application

current_user предполагает, что вы используете какую-то аутентификацию. csrf_meta_tag — встроенный помощник Rails. Обратите внимание, что я поместил свой js в последнюю строку тела. не кладите свои js в голову.

person Andrew WC Brown    schedule 15.03.2015
comment
Эндрю, возможно ли отправить частичное сообщение (create.js.erb: ‹%= j render @message %› вместо json? Я хотел бы использовать свое частичное сообщение _message, так как в нем есть некоторые условия. - person Sean Magyar; 25.01.2016
comment
Вы можете просто передать его как json, например. визуализировать json: {html: ‹yourhtml› } - person Andrew WC Brown; 12.02.2016