lib/angelo/base.rb in angelo-0.1.14 vs lib/angelo/base.rb in angelo-0.1.15
- old
+ new
@@ -4,17 +4,20 @@
include ParamsParser
include Celluloid::Logger
extend Forwardable
def_delegators :@responder, :content_type, :headers, :redirect, :request
+ def_delegators :@klass, :websockets, :sses, :sse_event, :sse_message
@@addr = DEFAULT_ADDR
@@port = DEFAULT_PORT
@@ping_time = DEFAULT_PING_TIME
@@log_level = DEFAULT_LOG_LEVEL
+ @@report_errors = false
+
if ARGV.any? and not Kernel.const_defined?('Minitest')
require 'optparse'
OptionParser.new { |op|
op.on('-p port', 'set the port (default is 4567)') { |val| @@port = Integer(val) }
op.on('-o addr', "set the host (default is #{@@addr})") { |val| @@addr = val }
@@ -85,27 +88,37 @@
routes[m][path] = Responder.new &block
end
end
def websocket path, &block
- routes[:websocket][path] = WebsocketResponder.new &block
+ routes[:websocket][path] = Responder::Websocket.new &block
end
+ def eventsource path, &block
+ routes[:get][path] = Responder::Eventsource.new &block
+ end
+
def on_pong &block
- WebsocketResponder.on_pong = block
+ Responder::Websocket.on_pong = block
end
def task name, &block
Angelo::Server.define_task name, &block
end
def websockets
- @websockets ||= Stash.new server
+ @websockets ||= Stash::Websocket.new server
@websockets.reject! &:closed?
@websockets
end
+ def sses
+ @sses ||= Stash::SSE.new server
+ @sses.reject! &:closed?
+ @sses
+ end
+
def content_type type
Responder.content_type type
end
def run addr = @@addr, port = @@port
@@ -124,12 +137,27 @@
lp = File.join(public_dir, path)
File.file?(lp) ? lp : nil
end
end
+ def sse_event event_name, data
+ data = data.to_json if Hash === data
+ SSE_EVENT_TEMPLATE % [event_name.to_s, data]
+ end
+
+ def sse_message data
+ data = data.to_json if Hash === data
+ SSE_DATA_TEMPLATE % data
+ end
+
end
+ def initialize responder
+ @responder = responder
+ @klass = self.class
+ end
+
def async meth, *args
self.class.server.async.__send__ meth, *args
end
def future meth, *args
@@ -142,12 +170,10 @@
when POST; parse_post_body
when PUT; parse_post_body
end
end
- def websockets; self.class.websockets; end
-
def request_headers
@request_headers ||= Hash.new do |hash, key|
if Symbol === key
k = key.to_s.upcase
k.gsub! UNDERSCORE, DASH
@@ -173,10 +199,23 @@
ws.socket << ::WebSocket::Message.ping.to_data
end
end
end
+ task :handle_event_source do |socket, block|
+ begin
+ block[socket]
+ rescue Reel::SocketError, IOError, SystemCallError => e
+ # probably closed on client
+ warn e.message if @@report_errors
+ socket.close unless socket.closed?
+ rescue => e
+ error e.inspect
+ socket.close unless socket.closed?
+ end
+ end
+
def halt status = 400, body = ''
throw :halt, HALT_STRUCT.new(status, body)
end
def send_file local_file, opts = {}
@@ -197,9 +236,23 @@
# Content-Length
#
headers CONTENT_LENGTH_HEADER_KEY => File.size(lp)
halt 200, File.read(lp)
+ end
+
+ def eventsource &block
+ headers SSE_HEADER
+ async :handle_event_source, responder.connection.detach.socket, block
+ halt 200, :sse
+ end
+
+ def report_errors?
+ @@report_errors
+ end
+
+ def sleep time
+ Celluloid.sleep time
end
end
end