Skip to content

Instantly share code, notes, and snippets.

@mironov
Forked from anonymous/oshi.rb
Created July 8, 2010 09:03
Show Gist options
  • Save mironov/467782 to your computer and use it in GitHub Desktop.
Save mironov/467782 to your computer and use it in GitHub Desktop.
require 'rubygems'
require 'eventmachine'
require 'em-websocket'
require 'json'
class Connection
attr_accessor :socket, :user_id
def initialize(socket, user_id)
@socket = socket
@user_id = user_id
end
end
class Oshi
attr_accessor :connections
def initialize()
@connections = {}
end
def connect(socket, user_id)
@connections[user_id] = Connection.new(socket, user_id)
puts "Number of Connections: #{@connections.size}"
end
def disconnect(socket, user_id)
@connections.delete(user_id)
end
def broadcast(message)
@connections.each do |user_id, connection|
connection.socket.send(message)
end
end
def send_message_to_user(user_id, message)
@connections[user_id].socket.send(message)
end
end
class RailsHandler < EventMachine::Connection
attr_accessor :oshi
def post_init
puts "RailsHandler connection connection opened"
end
def receive_data(data)
puts "Recieved RailsHandler message : #{data}"
data = JSON data
controller, action = data["pair"].split("#")
oshi.send action, *data["args"]
end
def unbind
puts "RailsHandler connection connection closed"
end
end
EventMachine.run {
@oshi = Oshi.new
host, rails_handler_port, web_socket_port = "192.localhost", 8090, 8080
EventMachine::start_server host, rails_handler_port, RailsHandler do |c|
c.oshi = @oshi
end
EventMachine::WebSocket.start(:host => host, :port => web_socket_port) do |socket|
socket.onopen {
user_id = socket.request["Query"]["user_id"]
@oshi.connect(socket, user_id)
puts "WebSocket connection opened for #{user_id}"
}
socket.onmessage { |message|
puts "Recieved WebSocket message: #{message}"
params = JSON message
reply = @oshi.send(params["action"], socket, params["data"]["user_id"])
#@oshi.send_message_to_user(params["data"]["user_id"], reply ) if reply
}
socket.onclose {
user_id = socket.request["Query"]["user_id"] if socket.request["Query"]
@oshi.disconnect(socket, user_id)
puts "WebSocket connection closed for #{user_id}"
}
end
}
class HomeController < ApplicationController
def test
oshi_push "Chat#broadcast", "#{current_user.name} has connected"
end
protected
def oshi_push(pair, *args)
host,port = "192.localhost", 8090
c = TCPSocket.open(host, port)
c.print({:pair => pair, :args => args}.to_json)
c.flush
c.close
end
end
end
# javascript in the view.
<% content_for :script do %>
jQuery(document).ready(function($){
ws = new WebSocket("ws://192.localhost:8080/oshi?user_id=<%= current_user.id %>");
function debug(str){ $("#debug").append("<p>"+str+"</p>"); };
ws.onopen = function() {
debug("connected...");
};
ws.onmessage = function(evt) {
$("#message").append("<p>"+evt.data+"</p>");
};
ws.onclose = function() {
debug("socket closed");
};
});
<% end %>
#message
#debug
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment