开发者

Ruby on Rails 3.0 Pusher Chat

I'm trying to implement something similar to http://开发者_如何学Cpusher-chat.heroku.com/

However, I cannot figure out how to call an action without the page refreshing.

The page refreshing defeats the purpose of using pusher.

So far I have created a chat table, with attributes account_id and message.

In my chat controller I have the following:

 def create
    account = Account.getAccountById(session[:user])
    if params[:message].blank?
        @title = "Chat"
        @chatLog = Chat.find(
                :all,
                :order => "created_at ASC",
                :limit => 20
        )
        render :action => :index
    else
        chatter = Chat.new(
            :account_id => account.id,
            :message => params[:message]
        )
        payload = {
            "account_id" => chatter.account_id,
            "message" => chatter.message
        }
        if chatter.save
            Pusher['chat-channel'].trigger('send_message', payload)
            @title = "Chat"
            @chatLog = Chat.find(
                :all,
                :order => "created_at ASC",
                :limit => 20
            )
            render :action => :index
        else
            render :action => :index
        end
    end
rescue ActiveRecord::RecordNotFound
    reset_session
    redirect_to(new_account_path)
end

In my chat.js file I have the following:

 $(document).ready(function() {
// Enable pusher logging - don't include this in production
Pusher.log = function(message) {
    if (window.console && window.console.log) window.console.log(message);
};

// Flash fallback logging - don't include this in production
WEB_SOCKET_DEBUG = true;

var pusher = new Pusher('62651eca256339fa7fca');
var channel = pusher.subscribe('chat-channel');
channel.bind('send_message', function(chatter) {
    $('#loading').show();
});
 });

I've never built anything like this before, so I would appreciate any help.

I know there has to be a lot more javascript involved.

Thank you,

Brian


To call an action without refreshing you should use ajax.

I haven't tried pusher yet but it seems that whenever someone "submits" a new message, your application, it shall send to the pusher channel so it can broadcast to every "subscribed" client online.

If this is correct, you should think the whole thing as this:

When someone clicks on "new chat" it will create a new chat room, instantiate a new channel on pusher and save it on database. This will generate the identification on the url, that you can send to someone so that they can join your chat.

On the chat screen, you will have one big div that will render the chat and on input text field where you send messages. This particular field will submit to your application using ajax your chat ID and the message.

On your chat controller when you receive this information, you go get the pusher channel id on database for that chat room, save message on database for history and send it back to every user connected on that room with pusher.

The logic to render the text on the chat will be done by client side javascript.


Hmmh, my approach would be to use a Javascript timer which calls an AJAX-script every two seconds to get the new chat entries since the last request - and then refresh only the chatbox. Like so:

var latest_entry_number = 0;
var chatter = window.setInterval("getNewestEntries()",2000);
function getNewestEntries() {
  $.ajax({
    url: "/path/to/latest_entries",
    type: "POST",
    dataType: "JSON",
    data: {latest_entry: latest_entry_number}
    success: appendEntries
  });
}
function appendEntries(data) {
  latest_entry_number = data.latest_entry;
  $.each(data.entries, function(key,val){
    //append the entries to the chat
  })  
}

And the controller action would look like this:

def latest_entries
  data[:latest_entry] = get_latest_entry # each entry gets a consecutive, ascending number
  data[:entries] = get_entries_since(params[:latest_entry_number]) # get all entries done since that number
                            # Should be an array
  render :json => data
end

Or something like that.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜