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 inwebsoket.rb
(first create websoket.rb file
insideconfig/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
In my case I am using this inside the **Notification.rb to sending notification.**Now use this method inside your model or controller where you want.
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 terminalrackup 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
How to Create a Custom Sort Method in Ruby
Error Could Not Find I18N-0.7.0 in Any of The Sources
Ruby Readline Fails If Process Started with Arguments
Running "Bundle Install" Fails and Asks Me to Run "Bundle Install"
Error Installing Rdoc Documentation: Incompatible Encoding Regexp Match
Obtaining Number of Block Parameters
Converting Ruby Hashes to Arrays
How to Use Reform to Prepopulate for Featured Objects
How to Validate This Hash Parameter
Setting Up Configuration Settings When Writing a Gem
Deleting a Specific Line in a Text File
How to Make Fish Shell Use an Rvm Ruby by Default
How to Tell Unicorn to Understand Heroku's Signals
Using Rails Form Helpers with Serialized Custom Classes