Личные сообщения с Faye и Rails

Я использую faye gem, упомянутый в railscast, позволяющий приложениям отправлять сообщения. Проблема в том, что он отправляет сообщения всем открытым клиентам чата. Мне нужно, чтобы они были частными. С Фэй можно получать личные сообщения, но это основано на URL-адресе. Например, все сообщения будут отправлены на site.com/foo. Но в моей модели чат не имеет определенного URL-адреса. Потому что чат — это просто набор сообщений, отправленных вам этим пользователем.

Таким образом, если вы вошли в систему как Адам site.com/messages/eve, вы могли бы поговорить с Евой, но для Евы все наоборот. site.com/messages/adam. Таким образом, приватный чат с URL-адресом, по-видимому, не может быть и речи.

Любые указатели?

messages_controller.rb (запуск ajax)

def create
  @message = Message.new(message_params)
  @message.save
end 

create.js.erb (вызов широковещательного метода)

<% broadcast params[:message][:username] do %>
  $(".text-wrap").append("<%= current_user.name %> <%= @message.body %></div>");
<% end %>

метод трансляции (отправка на сервер faye)

def broadcast(user, &block)
  channel = "/messages/#{user}"
  message = {:channel => channel, :data => capture(&block)}
  uri = URI.parse("http://localhost:9292/faye")
  Net::HTTP.post_form(uri, :message => message.to_json)
end

application.js (подписка сервера faye на /messages/*)

$(function(){
    var faye = new Faye.Client('http://localhost:9292/faye');
    var subscription = faye.subscribe('/messages/*', function(message) {
        eval(message);
    });
});

person Alain Goldman    schedule 26.11.2014    source источник


Ответы (1)


Я решил это! Проблема заключалась в том, что у меня была функция подписки в application.js, что означало, что она запускала javascript подписки на каждой странице. Вместо этого я сделал это в нижней части страницы чата, на которую я подписался /messages/eve/adam. Вот как я это сделал:

<script>  
  $(function(){
    var faye = new Faye.Client('http://localhost:9292/faye');
    var subscription = faye.subscribe('/messages/#{current_user.username}/#{@user.username}', function(message) {
      eval(message);
    });
  });
</script>

Затем в широковещательном методе я убедился, что информация отправляется только в нужное место.

def broadcast(user, &block)
  channel = "/messages/#{current_user.username}/#{user}"
  message = {:channel => channel, :data => capture(&block)}
  uri = URI.parse("http://localhost:9292/faye")
  Net::HTTP.post_form(uri, :message => message.to_json)
end 
person Alain Goldman    schedule 26.11.2014