Использование Private-pub с каналами, у которых есть ключи сегмента и вариант coffeescript

Я пытаюсь воспроизвести систему push-уведомлений, аналогичную системе Facebook, используя private_pub. В идеале я хотел бы связать это, чтобы показывать уведомления с помощью драгоценного камня, такого как gritter (другие предложения драгоценного камня приветствуются )

Всякий раз, когда вызывается определенное действие от контроллера, я хочу отправить уведомление всем подписчикам, которые являются частью определенного идентификатора. Пока вы вошли в систему, вы подписаны на канал, что достигается путем размещения subscribe_to в макетах.

в представлении:

<%= subscribe_to "/messages/#{@group_id}" %>

в контроллере

PrivatePub.publish_to("/messages/#{@group_id}", "alert('test')")

это работает просто отлично, однако я хотел бы иметь что-то более сложное, чем alert в качестве ответа (например, уведомление о песочнице), поэтому вместо этого:

PrivatePub.publish_to("/messages/#{@group_id}", data: @some_data)

Следуя руководству, они используют для этого coffeescript. Однако я не могу получить простое оповещение (вероятно, из-за идентификатора в канале)

В это вопрос, OP смог решить эту проблему, используя представление js.erb. Но я не могу заставить его работать.

Отказ от ответственности: мои знания js и coffeescript почти равны нулю.

Любая помощь приветствуется :)


ИЗМЕНИТЬ

Еще немного информации: у меня есть метод в контроллере, который является частью общедоступного API и ожидает запроса POST. Если все в порядке, он отправляет ответ об успешном завершении JSON. Кроме того, этот же метод отправляет уведомление всем пользователям определенной группы.

Мне действительно удалось заставить это работать, поместив это в контроллер:

метод обратного вызова:

respond_to do |format|
    format.js #-> calls callback.js.erb
    #format.json { render json: {"success" => true}.to_json }
end

и поместите песчинки в my_api_controller/callback.js.erb:

<% publish_to "/messages/#{@group_id}" do %>
    <%= add_gritter(
    "Nova " + link_to("reserva", reservation_path(@r)) + " de #{@channel} para " + 
    link_to(@hostel_name, hostel_path(@hostel_id)),
    :title => "Nova reserva!",
    :sticky => true,
    :image => :notice
) %>
<% end %>

примечание: так как подписка на канал делается в каждом просмотре (через макет), вы можете получать уведомление на любой странице/просмотре

Моя проблема на данный момент, как вы можете догадаться, это ответ JSON. Поскольку я не могу отобразить два ответа, вызывается только js.erb, но ответ JSON никогда не отправляется


person Cristiano Sousa    schedule 14.01.2014    source источник
comment
Собирался сразу предложить использовать для этого JS. Позвольте мне написать ответ   -  person Richard Peck    schedule 14.01.2014


Ответы (3)


Хотя у меня нет большого опыта работы с этим камнем, вот что может помочь:


JS

На стороне клиента ваш JS в основном работает с eventlistener. на объекте private_pub (определяется, когда вы включаете private_pub / gritter JS на свою страницу), который вы можете использовать для выполнения других действий (оповещения о звонках, добавление данных на страницу и т. д.)

Кажется, ваш сервер работает, это просто получение и обработка данных с сервера, с которым вы боретесь. Чтобы исправить это, вы можете сделать 2 вещи: 1) запустить стандартный вызов JS из application.js или запустить файл js из действия вашего контроллера:


Контроллер

Согласно документации private_pub, вы должны сделать это, чтобы создать файл JS:

#app/controllers/your_controller.rb
def create
    @message = "Hello"

    respond_to do |format| 
        format.html { PrivatePub.publish_to("/messages/#{@group_id}", "alert('test')") }
        format.js #-> calls create.js.erb
    end
end 

#app/views/your_controller/create.js.erb
<% publish_to "/messages/new" do %>
  $("#chat").append("<%= j render(@messages) %>");
<% end %>

Браузер

#app/assets/javascripts/application.js.coffee
PrivatePub.subscribe("/messages/new", (data, channel) ->
      alert data.message.content
person Richard Peck    schedule 14.01.2014
comment
Спасибо за ответ, я отредактировал свой вопрос для получения дополнительной информации. - person Cristiano Sousa; 15.01.2014

Я смог добиться этого, напрямую добавив скрипт песочницы в метод publish_to паба Приват.

В моем контроллере:

PrivatePub.publish_to 
  "/some/URI/#{entity.id}"
 ,"jQuery.gritter.add({
      image: '#{ActionController::Base.helpers.asset_path('notice.png')}'
    , sticky: true
    ,title:'#{t('some_title')}'
    , text: '#{t('some text'}' 
});"

render json: {"error"=>{"code"=>20,"msg"=>e.message},"success" => false}.to_json

По сути, я смог опубликовать в PrivatePub, не прибегая к ответу html, что позволило мне вернуть ответ JSON, как предполагалось.

person Cristiano Sousa    schedule 11.03.2015

Я думаю, вы можете решить свою проблему с помощью гема gon, как показано ниже:

In view

<%= subscribe_to "/messages/#{@group_id}" %>

In controller

gon.group_id = @group_id
PrivatePub.publish_to("/messages/#{@group_id}", message: @message)

In messages.coffee

if gon.group_id
  PrivatePub.subscribe "/messages/#{gon.group_id}", (data, channel) ->
    jQuery.gritter.add
      image: '/assets/notice.png'
      title: 'Notification!'
      text: data.message.content

Но иногда gon.group_id может создавать проблемы, так что вам нужно позаботиться об этом.

Итак, я рекомендую использовать js.erb, который прост, и мы можем легко получить доступ к переменной controller's в файле js.erb.

Надеюсь, что ответит на вашу проблему.

person przbadu    schedule 10.03.2015