Created
December 14, 2009 03:59
-
-
Save mikewadhera/255763 to your computer and use it in GitHub Desktop.
ruby on netty
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Purely experimental exercise in exploring ideas for a JRuby gem for Netty -- http://jboss.org/netty | |
# Based on TimeClient example in Netty docs | |
require "java" | |
require "netty" | |
require "unix_time" | |
TimeClient = TcpNioClient.new do |pipeline| | |
pipeline.insert :frame_decoder do | |
def decode(context, channel, buffer) | |
UnixTime.new(buffer.read_integer) unless buffer.readable_bytes < 4 | |
end | |
end | |
pipeline.insert :handler do | |
on_new_message do |context, event| | |
puts event.message.inspect | |
event.channel.close | |
end | |
end | |
end | |
TimeClient.connect :host => "localhost", :port => 8080 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Purely experimental exercise in exploring ideas for a JRuby gem for Netty -- http://jboss.org/netty | |
# Based on TimeServer example in Netty docs | |
require "java" | |
require "netty" | |
require "unix_time" | |
# A custom Handler that extends ChannelHandlers::Simple a SimpleChannelHandler | |
# Tries to separate the handler's lifecycle from the independent handler actions | |
class TimeServerHandler < ChannelHandlers::Simple | |
on_connect :write_unix_time | |
on_open :add_to_active_channels | |
def write_unix_time(context, event) | |
time = UnixTime.new(java.lang.System.current_time_millis / 1000) | |
write = event.channel.write(time) | |
write.add_listener(:close) # sugar for add_listener(Channel::ChannelFutureListener::CLOSE) | |
end | |
# Maybe push this into Base, if possible -- could also capture other common actions | |
def add_to_active_channels(context, event) | |
TimeServer.active_channels << event.channel | |
end | |
# Hook for exception handling. Base implementation prints stack trace on standard error & closes channel | |
def rescue_exception(exception, channel) | |
MyLogger.error(exception) | |
super | |
end | |
end | |
# DSL for defining a pipeline factory, inspired by Rails routes.rb | |
pipeline_factory = PipelineFactory.assemble do |pipeline| | |
# Alternate #insert forms: | |
# pipeline.insert TimeEncoder.new -- infers name from class | |
pipeline.insert :encoder do | |
on_write_request do |context, event| | |
buffer = Buffer.new(4).write_integer(event.message) # sugar for write_int(arg.to_i) | |
write(context, event.future, buffer) # what about doing this automatically if the method/block returns a Buffer? | |
end | |
end | |
pipeline.insert :handler, TimeServerHandler.new | |
end | |
# Server class bootstrapping common combos of transport/IO Model, handling shutdown & active channels, joining event loop, etc. | |
# One could imagine similar classes for client side | |
# Alternate #initialize forms: | |
# TcpNioServer.new(pipeline_factory, :port => 8080, :threads => 5, :shutdown => ["TERM"]) -- uses separately defined PipelineFactory above | |
TimeServer = TcpNioServer.new :port => 8080 do |pipeline| # this form yields a PipelineFactory for inline assembly | |
pipeline.insert :encoder do | |
on_write_request do |context, event| | |
buffer = Buffer.new(4).write_integer(event.message) # sugar for write_int(arg.to_i) | |
write(context, event.future, buffer) # what about doing this automatically if the method/block returns a Buffer? | |
end | |
end | |
pipeline.insert :handler, TimeServerHandler.new | |
end | |
puts "TimeServer running on #{TimeServer.port}" | |
TimeServer.join # just future.await_uninterruptibly |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class UnixTime | |
attr_reader :value | |
def initialize(value) | |
@value = value | |
end | |
def to_i | |
@value | |
end | |
def inspect | |
java.util.Date.new(@value * 1000).to_string | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment