module SocketReactive
Constants
- TICK
duration of sleep when active wait (
wait_end
,on_timer…)
Public Class Methods
# File lib/minitcp.rb, line 203 def self.make_socket_reactive(socket) socket.extend(SocketReactive) socket.data_readed="" end
Public Instance Methods
async yield after a duration, if socket is open return thread spawned, which can be kill
# File lib/minitcp.rb, line 157 def after(duration_ms) Thread.new() do begin sleep(duration_ms/1000.0) yield unless self.connected?() rescue Exception => e $stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}" end end end
Test if a socket is open. (use socket.remote_address() !)
# File lib/minitcp.rb, line 197 def connected?() (self.remote_address rescue nil) ? true : false end
# File lib/minitcp.rb, line 16 def data_readed() @data_readed||=strempty end
# File lib/minitcp.rb, line 15 def data_readed=(v) @data_readed=v end
async wait and read data on socket, yield values readed, return thread spawned, which can be kill
# File lib/minitcp.rb, line 74 def on_any_receive() Thread.new() do begin if self.data_readed.size>0 buff,self.data_readed=self.data_readed,strempty yield(buff) end loop do data=(self.recv(64*1024) rescue nil) data && data.size>0 ? yield(data) : break end rescue Exception => e $stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}" end close rescue nil end end
async yield on received n bytes return thread spawned, which can be kill
# File lib/minitcp.rb, line 95 def on_n_receive(sizemax=1,&b) Thread.new() do begin receive_n_bytes(sizemax,true,&b) rescue Exception => e $stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}" end end end
async yield on received data until end-buffer string end-buffer can be string or regexp (args of data.split(,2)) return thread spawned, which can be kill this read some extra data. they can be retrieve with in socket.data_readed. data_readed
is use for next calls to receives_n_byte/receive_sep
# File lib/minitcp.rb, line 145 def on_receive_sep(separator,sizemax=1024,&b) Thread.new() do begin receive_sep(separator,sizemax,looping=true,&b) rescue Exception => e $stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}" end end end
async yield periodicaly, if socket is open return thread spawned, which can be kill
# File lib/minitcp.rb, line 170 def on_timer(value=1000) Thread.new() { begin nbtick=(value/TICK)+1 loop do i=0 sleep(TICK/1000.0) while self.connected?() && (i+=1)<nbtick self.connected?() ? yield() : break end rescue Exception => e $stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}" end } end
read n byte, block the caller, return nil if socket if close if block is defined, it is yield with data, method return whith the value of yield if looping is true, the method loop until socket close, (or current thread is killed)
# File lib/minitcp.rb, line 21 def receive_n_bytes(sizemax,looping=false,&b) s=sizemax if self.data_readed.size>=sizemax buff,self.data_readed=self.data_readed[0..sizemax-1],self.data_readed[sizemax..-1] buff=b.call(buff) if block_given? return buff unless looping end s=sizemax-self.data_readed.size loop do #p ["waiting ",s,data_readed] sd=s>1024 ? 1024 : s data=(self.recv(sd) rescue (p $!;nil)) #p "nrec: w#{sizemax}/ rec:#{(data||'').size} / #{sd} old=#{data_readed.size} /// #{(data||'').size<70 ? data : "."}" if data && data.size>0 self.data_readed=self.data_readed+data s=sizemax-self.data_readed.size if s<=0 buff,self.data_readed=self.data_readed,"" s=sizemax buff=b.call(buff) if block_given? return buff unless looping end else close rescue nil break # socket close end end #loop end
read until separator reached, block the caller, return nil if socket is close if block is defined, it is yield with data, method return whith the value of yield if looping is true, the method loop until socket close, (or current thread is killed) this read some extra data. they can be retrieve with in socket.data_readed. data_readed
is use for next calls to receives_n_byte/receive_sep
# File lib/minitcp.rb, line 110 def receive_sep(separator,sizemax=1024,looping=false,&b) if self.data_readed.size>0 a=self.data_readed.split(separator,2) while a.size>1 buff= a.size>2 ? a[0..-2] : a.first self.data_readed=a.last buff=b.call(buff) if block_given? return buff unless looping a=self.data_readed.split(separator,2) end end loop do data=(self.recv(sizemax-self.data_readed.size) rescue nil) if data && data.size>0 self.data_readed=self.data_readed+data a=(self.data_readed).split(separator,2) while a.size>1 buff= a.size>2 ? a[0..-2] : a.first self.data_readed=a.last buff=b.call(buff) if block_given? return buff unless looping a=(self.data_readed).split(separator,2) end else close rescue nil break end end end
# File lib/minitcp.rb, line 62 def received_any_timeout(sizemax,timeout_ms) timeout(timeout_ms/1000.0) { return recv(sizemax) } rescue Timeout::Error return nil rescue Exception => e $stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}" end
wait n byte or timeout. if block is defined, it is yielded with data return nil if timeout/socket closed, or data if no bloc, or yield value
# File lib/minitcp.rb, line 51 def received_n_timeout(sizemax,timeout_ms,&b) timeout(timeout_ms/1000.0) { ret=receive_n_bytes(sizemax,false,&b) return ret } rescue Timeout::Error return nil rescue Exception => e $stdout.puts "#{e} :\n #{e.backtrace.join("\n ")}" end
# File lib/minitcp.rb, line 14 def strempty() ''.force_encoding Encoding::BINARY end
wait until curent socket is close.
# File lib/minitcp.rb, line 186 def wait_end() begin loop do sleep(TICK/1000.0) while (self.connected?() rescue nil) break end rescue Exception => e end end