I want to use node.js with my Rails-Project to serve asynchronous io. I don't want to use juggernaut, faye or something like this, because I need clean connections with web-socket, server-sent events and spdy without an alternative. My first try to use node.js is now to use Socket.io, just to get in use with serving data to a node.js-module with JavaScript. But it doesn't work at all.
My application.js looks like this:
// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require_tree .
window.socket = io.connect('http://localhost:8080/');
The requirements for io get correctly loaded in my application.html.erb:
<%= javascript_include_tag "application", "http://localhost:8080/socket.io/socket.io.js" %>
Now I want to use the socket to emit a event sent to all listening clients like this in a create.js.erb:
$(function() {
window.socket.emit('message', <%= @message =>);
};
$("#new_article")[0].reset();
The message gets created in the ArticlesCrontroller this way:
def create
@article = current_user.articles.build(params[:article])
if @article.save
msg = {:data => @article.to_json}
@message = msg.to_json
end
end
I listen at this event in an other view called index.js.erb this way:
$(function() {
window.socket.on('message', function (msg) {
$("#articles").prepend(<%= escape_javascript render(Article.new.from_json(msg.data)) %>);
});
});
The Socket.io looks like this:
var io = require('socket.io').listen(8080);
io.sockets.on('connection', function (socket) {
socket.on('message', function () { });
socket.on('disconnect', function () { });
});
and seems to work right, because it tells me right how it serves the requested js-File:
info - socket.io started
debug - served static /socket.io.js
But it doesn't work at all, although the create.js.erb gets rendered without an error:
Rendered articles/create.js.erb (0.5ms)
Completed 200 OK in 268ms (Views: 70.0ms | ActiveRecord: 14.6ms)
Even the jQuery-Function for resetting the form gets not executed, what works without the try to emit the socket-event. The article gets saved to the database correctly, so that isn't the problem. Can someone tell me where the problem might be?
Update: I figured out by using the JavaScript-debugger of chrome, that the problem starts with the definition of window.socket in the application.js. The error-code is:
Uncaught ReferenceError: io is not defined
(anonymous function)
But io is defined in the socket.io.js-File I load in my application.html.erb. I did a workaround for application.js this way:
$.getScript('http://localhost:8080/socket.io/socket.io.js', function(){
window.socket = io.connect('http://localhost:8080/');
});
The question is now: Why do I have to get the script this way, although it is loadet in the application.html.erb? But despite this workaround the create.js.erb still doesn't work yet. I will try to workaround that after having a bit of sleep.