lib/rlyeh/connection.rb in rlyeh-0.0.2 vs lib/rlyeh/connection.rb in rlyeh-0.1.1
- old
+ new
@@ -1,55 +1,110 @@
+require 'celluloid'
+require 'forwardable'
+require 'rlyeh/logger'
+require 'rlyeh/sender'
+require 'rlyeh/worker'
require 'rlyeh/environment'
-require 'rlyeh/filters'
-require 'rlyeh/sendable'
module Rlyeh
- class Connection < EventMachine::Connection
- include EventMachine::Protocols::LineText2
- include Rlyeh::Sendable
+ class Connection
+ include Rlyeh::Logger
+ include Rlyeh::Sender
+ include Rlyeh::Worker
+ extend Forwardable
- attr_reader :server, :app_class, :options
- attr_reader :app, :session
+ attr_reader :server, :socket
+ attr_reader :app, :host, :port, :session
- def initialize(server, app_class, options)
+ def_delegators :@socket, :close, :closed?
+
+ BUFFER_SIZE = 4096
+
+ def initialize(server, socket)
@server = server
- @app_class = app_class
- @options = options
- set_delimiter "\r\n"
+ @socket = socket
+ _, @port, @host = @socket.peeraddr
+ @app = @server.app_class.new nil
+
+ debug "Connection started: #{@host}:#{@port}"
end
- def post_init
- @app = app_class.new nil, @options
+ def close
+ @socket.close unless @socket.closed?
+
+ if attached?
+ @session.detach self
+
+ if @session.empty?
+ @session.close
+ @server.sessions.delete @session.id
+ end
+ end
+
+ debug "Connection closed: #{@host}:#{@port}"
end
- def unbind
- @server.unbind self
+ def run
+ catch :quit do
+ read_each do |data|
+ invoke do
+ process data
+ end
+ end
+ end
end
- def receive_line(data)
+ def read_each(&block)
+ loop do
+ @buffer ||= ''.force_encoding('ASCII-8BIT')
+ @buffer << @socket.readpartial(BUFFER_SIZE).force_encoding('ASCII-8BIT')
+
+ while data = @buffer.slice!(/(.+)\n/, 1)
+ block.call data.chomp if block
+ end
+ end
+ rescue EOFError => e
+ # client disconnected
+ rescue Celluloid::Task::TerminatedError
+ # kill a running task
+ end
+
+ def process(data)
env = Rlyeh::Environment.new
+ env.version = Rlyeh::VERSION
env.data = data
env.server = @server
env.connection = self
- env.settings = @app_class.settings
+ env.settings = @server.app_class.settings
catch :halt do
- @app.call env
+ begin
+ @app.call env
+ rescue Exception => e
+ crash e
+ end
end
end
- def attached(session)
+ def send_data(data, multicast = true)
+ data = data.to_s
+ if multicast && attached?
+ @session.send_data data
+ else
+ @socket.write data
+ end
+ end
+
+ def attach(session)
@session = session
end
- def detached(session)
+ def detach(session)
@session = nil
end
def attached?
!!@session
end
-
- include Rlyeh::Filters
- define_filters :attached, :detached
end
end
+