module UV
BufferedTokenizer
takes a delimiter upon instantiation. It allows input to be spoon-fed from some outside source which receives arbitrary length datagrams which may-or-may-not contain the token by which entities are delimited.
@example Using BufferedTokernizer to parse lines out of incoming data
module LineBufferedConnection def receive_data(data) (@buffer ||= BufferedTokenizer.new(delimiter: "\n")).extract(data).each do |line| receive_line(line) end end end
Based on code from github.com/chernesk/net-ping/blob/master/lib/net/ping/external.rb
Constants
- VERSION
Public Class Methods
attach_server(sock, handler, *args)
click to toggle source
# File lib/uv-rays.rb, line 68 def self.attach_server(sock, handler, *args) thread = reactor # Get the reactor running on this thread raise ThreadError, "There is no Libuv reactor running on the current thread" if thread.nil? klass = klass_from_handler(InboundConnection, handler, *args) sd = sock.respond_to?(:fileno) ? sock.fileno : sock UV::TcpServer.new thread, sd, sd, klass, *args end
connect(server, port, handler, *args)
click to toggle source
# File lib/uv-rays.rb, line 52 def self.connect(server, port, handler, *args) klass = klass_from_handler(OutboundConnection, handler, *args) c = klass.new server, port c.post_init *args c end
klass_from_handler(klass, handler = nil, *args)
click to toggle source
@private
# File lib/uv-rays.rb, line 28 def self.klass_from_handler(klass, handler = nil, *args) klass = if handler and handler.is_a?(Class) raise ArgumentError, "must provide module or subclass of #{klass.name}" unless klass >= handler handler elsif handler begin handler::UR_CONNECTION_CLASS rescue NameError handler::const_set(:UR_CONNECTION_CLASS, Class.new(klass) {include handler}) end else klass end arity = klass.instance_method(:post_init).arity expected = arity >= 0 ? arity : -(arity + 1) if (arity >= 0 and args.size != expected) or (arity < 0 and args.size < expected) raise ArgumentError, "wrong number of arguments for #{klass}#post_init (#{args.size} for #{expected})" end klass end
open_datagram_socket(handler, server = nil, port = nil, *args)
click to toggle source
# File lib/uv-rays.rb, line 78 def self.open_datagram_socket(handler, server = nil, port = nil, *args) klass = klass_from_handler(DatagramConnection, handler, *args) c = klass.new server, port c.post_init *args c end
start_server(server, port, handler, *args)
click to toggle source
# File lib/uv-rays.rb, line 60 def self.start_server(server, port, handler, *args) thread = reactor # Get the reactor running on this thread raise ThreadError, "There is no Libuv reactor running on the current thread" if thread.nil? klass = klass_from_handler(InboundConnection, handler, *args) UV::TcpServer.new thread, server, port, klass, *args end
try_connect(tcp, handler, server, port)
click to toggle source
# File lib/uv-rays/connection.rb, line 6 def self.try_connect(tcp, handler, server, port) if IPAddress.valid? server tcp.finally { handler.on_close } tcp.progress { |*data| handler.on_read(*data) } tcp.connect server, port do tcp.enable_nodelay tcp.start_tls(handler.using_tls) if handler.using_tls # on_connect could call use_tls so must come after start_tls handler.on_connect(tcp) tcp.start_read end else tcp.reactor.lookup(server, wait: false).then( proc { |result| UV.try_connect(tcp, handler, result[0][0], port) }, proc { |failure| # TODO:: Log error on reactor handler.on_close } ) end end