0

I am following this railscast that it explains how to implement a chat application. I have followed everything step by step, and it seems to be working until the point I started using redis for the publish/subscribe version of it to make it faster, but my application is not updating the chats now. I have to refresh the page each time a new message comes in!

Here is my code:

class MessagesController < ApplicationController
    include ActionController::Live

  def index
    @messages = Message.all
  end

  def create
    response.headers["Content-Type"] = "text/javascript"
    @message = Message.create!(params[:message].permit(:content, :name))
    $redis.publish('messages.create',@message.to_json)
  end

  def events   
    response.headers["Content-Type"] = "text/event-stream"
    redis=Redis.new
    redis.psubscribe('messages.create') do |on|
      on.pmessage do |pattern, event, data|
       response.stream.write("event: #{event}\n")
      end
    end
    rescue IOError
      logger.info "Stream closed"
    ensure
      redis.quit
      response.stream.close  
    end
end

in messages/index.html.erb

<h1>Chat</h1>

<ul id="chat">
  <%= render @messages %>
</ul>

<%= form_for Message.new, remote: true do |f| %>
  <%= f.text_field :name, placeholder: "Name" %>
  <%= f.text_field :content %>
  <%= f.submit "Send" %>
<% end %>

I have a .js file in the assets/javascript folder which takes care of the listening to server events.

var evnt = new EventSource('/messages/events');

evnt.addEventListener('messages.create', function(e){
  var message;
  message = $.parseJSON(e.data).message;
  return $('#chat').append($('<li>').text("" + message.name + ": " + message.content));
});

I am starting the redis-server on a separate terminal like this

$: redis-server

I did not install redis using brew, just downloaded a tar file and untarred it. It is recognized by the system so it should be ok.

When I try the application it does not update the chats with the new messages. I need to refresh the page to make them show. Anyhelp?

Trt Trt
  • 5,330
  • 13
  • 53
  • 86

1 Answers1

3

Seems you do not write any data to the stream, only the event type.

redis.psubscribe('messages.*') do |on|
  on.pmessage do |pattern, event, data|
    response.stream.write("event: #{event}\n")
    response.stream.write("data: #{data}\n\n") # You are missing this line.
  end
end
Thomas Klemm
  • 10,678
  • 1
  • 51
  • 54