BeachRunnerFred BeachRunnerFred - 4 months ago 23
Ruby Question

How do I send a channel message using channel.trigger with websocket-rails gem

I'm building a simple real-time chat app to learn how to use websockets with RoR and I don't think I'm understanding how channels work because they're not doing what I expect. I can successfully send a message to my Rails app using the

dispatcher.trigger()
method, and use my websocket controller to broadcast a message to all clients that subscribe to the channel. That all works fine. What does NOT work is using a channel (via the
channel.trigger()
method) to send a message to other clients. The websocket-rails wiki says...


Channel events currently happen outside of the Event Router flow. They
are meant for broadcasting events to a group of connected clients
simultaneously. If you wish to handle events with actions on the
server, trigger the event on the main dispatcher and specify which
controller action should handle it using the Event Router.


If I understand this correctly, I should be able to user the
channel.trigger()
method to broadcast a message to clients connected to the channel, without the message being routed through my RoR app, but it should still reach the other connected clients. So here's my code...

var dispatcher = new WebSocketRails('localhost:3000/websocket');
var channel = dispatcher.subscribe('channel_name');

channel.bind('channel_message', function(data) {
alert(data.message);
});

$("#send_message_button").click(function() {
obj = {message: "test"};
channel.trigger('channel_message', obj);
});


With the code listed above, I would expect that when I click the button, it sends a channel message using
channel.trigger()
and the
channel_message
binding should be executed on all clients, displaying an alert that reads "test". That doesn't happen. I'm using Chrome tools to inspect the websocket traffic and it shows the message being sent...

["channel_message",{"id":113458,"channel":'channel_name',"data":{"message":"test"},"token":"96fd4f51-6321-4309-941f-38110635f86f"}]


...but no message is received. My questions are...


  1. Am I misunderstanding how channel-based websockets work with the websocket-rails gem?

  2. If not, what am I doing wrong?



Thanks in advance for all your wisdom!

Answer

I was able to reproduce a working copy based on an off-the-shelf solution from the wiki along with your very own code.

I've packaged the whole thing here. The files you might be interested are home_controller.rb, application.js and home/index.html.erb.

It seems your understanding of channel-based websockets is correct. About the code, make sure to load the websocket javascript files and to enclose your code inside a document.ready. I had the exact same problem you're having without the latter.

//= require websocket_rails/main

$(function() {
  // your code here...
});

Let me know if it works. Best Luck!