WebSocket for Ruby 学习
使用 Ruby Eventmachine 的 Websockets August 20th 2010
HTML5增加了很多新特性,使开发更便利,最终使用更舒心。这里我们讨论其中一个新特性:WebSockets。我们会基于 Ruby 的 Eventmachine gem 来实现.
先确保你的浏览器支持 WebSockets (如 Chrome, Safari, Firefox trunk).
设置 EventMachine
使用 EventMachine for WebSockets 非常简单,有个现成的 em-websockets gem。 启动 EventMachine.run block 就可以了, EventMachine::WebSocket.start 会干剩下的活。 It provides a socket object that resembles the javascript WebSocket spec with callbacks for onopen, onmessage, and onclose.
require ‘eventmachine’
require ’em-websocket’
@sockets = []
EventMachine.run do
EventMachine::WebSocket.start(:host => ‘0.0.0.0’, :port => 8080) do |socket|
socket.onopen do
@sockets << socket
end
socket.onmessage do |mess|
@sockets.each {|s| s.send mess}
end
socket.onclose do
@sockets.delete socket
end
end
end
本例子中, connected sockets 被添加到数组中,并在 onmessage 被触发时进行广播.
客户端
The client side script listens for keypresses and sends them to the websocket. On receiving a message, which is just a single letter in this case, the corresponding letter will be lit up.
var socket;
var alphabet = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”;
function animateCharacter(letter)
{
var upper = letter.toUpperCase();
$(‘#character_’ + upper)
.stop(true,true)
.animate({ opacity: 1}, 100)
.animate({ opacity: .2}, 100);
}
function setup()
{
var target = $(‘#alphabet’);
for(var i = 0; i <=alphabet.length; i++)
{
var char = alphabet.charAt(i);
target.append(‘<span id=”character_’ + char +'”>’ + char + ‘</span’);
}
connect();
$(document).keypress(function(e){
var char = String.fromCharCode(e.keyCode);
socket.send(char);
});
};
function connect(){
socket = new WebSocket(‘ws://h.jxs.me:8080’);
socket.onmessage = function(mess) {
animateCharacter(mess.data);
};
};
window.onload += setup();
With it all put together, WebSockets makes for a simple way to connect users together through the browser without plugins, polling, or other ugly frameworks
安装 EventMachine
Ruby gem 已经提供了 EventMachine,名字就是 eventmachine。运行 gem install eventmachine 即可安装。
提醒一点, EventMachine 需要系统安装有 C++ 编译器,用于编译本机二进制扩展模块
使用 EventMachine
从实例中学习,让我们开始吧
echo service
echo 服务是传统的 UNIX 服务,它的功能就是接受网络连接client 端的输入信息,然后逐字节的原样返回输出到client 。 使用 EventMachine 编写非常简单
#!/usr/bin/env ruby
require ‘rubygems’
require ‘eventmachine’
module EchoServer
def receive_data(data)
send_data(data)
end
end
运行以上代码会在 8080 端口启动一个 echo 监听进程,让我们逐步分析代码.
首先看代码下部的 EventMachine::run 调用。他开启了一个事件循环,其后跟了一个代码块,一般用于启动 clients 或 servers,他将在此次循环的生命周期中一直存在,不会终止,除非我们直接调用 EventMachine::stop_event_loop.
本实例中我们用 EventMachine::start_server 启动我们的 echo 服务。前面两个参数是服务器和端口号。绑定到 0.0.0.0:8080 上,意味着 EchoServer 服务将在本机的任意 ip 的 8080 端口上监听.
第三个参数是事件处理器(handler)。一般来说处理器会是一个 Ruby module 用于定义回调函数,通过模块也不会污染全局名字空间。这里 EchoServer 仅仅定义了 receive_data ,每当我们通过 connection 接收到数据它都会被触发.
最后,EchoServer module 在触发 receive_data 后调用 send_data ,它会通过前面初始化过的 connection 发送数据