Private Messages with Faye and Rails

Private messages with Faye and Rails

I solved it! The problem was that I had the subscribe function in application.js meaning it would run the subscribe javascript on each page. Instead what I did is at the bottom of the chat page view i subscribed to /messages/eve/adam. This is how I did that:

<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>

Then in the broadcast method I made sure to send the information to only the correct place.

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

How can I push to Faye Server from Rails Controller?

I did't use Event Machine but I use Fay-web Socket in rails , I am using thin web-server for my application to show notification.

First you add this line into you Gemfile

gem 'faye'
gem 'thin'

Now ! run bundle install command for install gem and it's
dependency.

Create a faye.ru file and add given line (a rackup file for run
Faye server ).

require 'rubygems'
require 'thin'
require 'faye'
faye_server = Faye::RackAdapter.new(:mount => '/faye', :timeout => 45)
run faye_server

Now add line to your application.erb file

<%= javascript_include_tag 'application', "http://localhost:9292/faye.js", 'data-turbolinks-track' => true %>

Create a method with name broadcast or any name which is
suitable for you in websoket.rb (first create websoket.rb file
inside config/initializers ) .

module Websocket
def broadcast(channel, msg)
message = {:channel => channel, :data => msg}
uri = URI.parse("http://localhost:9292/faye")
Net::HTTP.post_form(uri, :message => message.to_json)
end
end

Now use this method inside your model or controller where you want.

In my case I am using this inside the **Notification.rb to sending notification.**

Example

after_create :send_notificaton 

def send_notification
broadcast("/users/#{user.id}", {username: "#{user.full_name }", msg: "Hello you are invited for project--| #{project.name} | please check your mail"})
end

For subscriber

<div id="websocket" style="background-color: #999999;">
</div>
<script>
$(function () {
var faye = new Faye.Client('http://localhost:9292/faye');
faye.subscribe('/users/<%= current_user.id %>', function (data) {
$('#websocket').text(data.username + ": " + data.msg);
});
});
</script>

Now ! Run your faye.ru file using terminal

rackup faye.ru -s thin -E prodcution

For details
Faye websocket

Ruby on Rails with Faye, how to broadcast data to specific subcsriber

In your client side JavaScript, subscribe to a channel name based on the user (e.g. '/messages/userid_1234') and use that to send private messages from the server.

For security reasons, don't use the actual user ID or even a hash of the username or email, since someone could spoof a subscribe that way. Generate a random GUID on signup for each user and store that with your user's account details.

Why use Faye for chat and not use Ajax (rails)

Faye is establishing a connection that the server can push data to the client with. With Ajax the client must request data and if it doesn't know that new data is available (which is the case in a chat client) then it must poll periodically for new content.

Is it more efficient? If the chat system sees enough traffic that your poll period is getting new data every time, probably not. If, on the other hand, you have an idle chat room then all of that polling is going to be chewing up resources that could be avoided by having the server push the data.

The flip side of this is that you are keeping a connection open with the server. This could work against you if you have a large number of idle clients. Because of this, it would be context sensitive as to which approach is better, or perhaps even a hybrid approach (opening a Faye connection for active use and then idling out to Ajax polling on an infrequent basis).



Related Topics



Leave a reply



Submit