module SocketReactive

Constants

TICK

duration of sleep when active wait (wait_end,on_timer…)

Public Class Methods

make_socket_reactive(socket) click to toggle source
# File lib/minitcp.rb, line 203
def self.make_socket_reactive(socket)
  socket.extend(SocketReactive)
  socket.data_readed=""
end

Public Instance Methods

after(duration_ms) { || ... } click to toggle source

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
connected?() click to toggle source

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
data_readed() click to toggle source
# File lib/minitcp.rb, line 16
def data_readed()   @data_readed||=strempty end
data_readed=(v) click to toggle source
# File lib/minitcp.rb, line 15
def data_readed=(v) @data_readed=v end
on_any_receive() { |buff| ... } click to toggle source

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
on_n_receive(sizemax=1,&b) click to toggle source

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
on_receive_sep(separator,sizemax=1024,&b) click to toggle source

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
on_timer(value=1000) { || ... } click to toggle source

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
receive_n_bytes(sizemax,looping=false,&b) click to toggle source

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
receive_sep(separator,sizemax=1024,looping=false,&b) click to toggle source

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
received_any_timeout(sizemax,timeout_ms) click to toggle source
# 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
received_n_timeout(sizemax,timeout_ms,&b) click to toggle source

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
strempty() click to toggle source
# File lib/minitcp.rb, line 14
def strempty() ''.force_encoding Encoding::BINARY end
wait_end() click to toggle source

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