Module: SocketReactive

Defined in:
lib/minitcp.rb

Constant Summary collapse

TICK =

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

600

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.make_socket_reactive(socket) ⇒ Object



203
204
205
206
# File 'lib/minitcp.rb', line 203

def self.make_socket_reactive(socket)
  socket.extend(SocketReactive)
  socket.data_readed=""
end

Instance Method Details

#after(duration_ms) ⇒ Object

async yield after a duration, if socket is open return thread spawned, which can be kill



157
158
159
160
161
162
163
164
165
166
# 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?Boolean

Test if a socket is open. (use socket.remote_address() !)

Returns:

  • (Boolean)


197
198
199
# File 'lib/minitcp.rb', line 197

def connected?()
  (self.remote_address rescue nil) ? true : false
end

#data_readedObject



16
# File 'lib/minitcp.rb', line 16

def data_readed()   @data_readed||=strempty end

#data_readed=(v) ⇒ Object



15
# File 'lib/minitcp.rb', line 15

def data_readed=(v) @data_readed=v end

#on_any_receiveObject

async wait and read data on socket, yield values readed, return thread spawned, which can be kill



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# 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) ⇒ Object

async yield on received n bytes return thread spawned, which can be kill



95
96
97
98
99
100
101
102
103
# 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) ⇒ Object

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



145
146
147
148
149
150
151
152
153
# 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) ⇒ Object

async yield periodicaly, if socket is open return thread spawned, which can be kill



170
171
172
173
174
175
176
177
178
179
180
181
182
183
# 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) ⇒ Object

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)



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 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) ⇒ Object

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



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# 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) ⇒ Object



62
63
64
65
66
67
68
69
70
# 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) ⇒ Object

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



51
52
53
54
55
56
57
58
59
60
# 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

#stremptyObject



14
# File 'lib/minitcp.rb', line 14

def strempty() ''.force_encoding Encoding::BINARY end

#wait_endObject

wait until curent socket is close.



186
187
188
189
190
191
192
193
194
# 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