Class: Iodine::Protocol
- Inherits:
-
Object
- Object
- Iodine::Protocol
- Defined in:
- lib/iodine/protocol.rb
Overview
This is the Basic Iodine server unit - a network protocol.
A new protocol instance will be created for every network connection.
The recommended use is to inherit this class and override any of the following:
- on_open
-
called whenever the Protocol is initialized. Override this to initialize the Protocol object.
- on_message(data)
-
called whenever data is received from the IO. Override this to implement the actual network protocol.
- on_close
-
called AFTER the Protocol’s IO is closed.
- on_shutdown
-
called when the server’s shutdown process had started and BEFORE the Protocol’s IO is closed. It allows graceful shutdown for network protocols.
- ping
-
called when timeout was reached. see #set_timeout
Once the network protocol class was created, remember to tell Iodine about it:
class MyProtocol << Iodine::Protocol
# your code here
end
# tell Iodine
Iodine.protocol = MyProtocol
Direct Known Subclasses
Base::Listener, Http::Http1, Http::Http2, Http::Websockets, SSLConnector
Instance Attribute Summary collapse
-
#io ⇒ Object
readonly
returns the IO object.
Class Method Summary collapse
-
.each ⇒ Enumerable
if a block is passed, than this method exceutes the block.
Instance Method Summary collapse
-
#call ⇒ Object
Called by Iodine whenever there is data in the IO’s read buffer.
-
#close ⇒ nil
(also: #disconnect)
Closes the IO object.
- #closed? ⇒ Boolean
-
#id ⇒ Object
returns the connection’s unique local ID as a Hex string.
-
#initialize(io) ⇒ Protocol
constructor
This method is used by Iodine to initialized the Protocol.
-
#on_close ⇒ Object
This method is called AFTER the Protocol’s IO is closed - it will only be called once.
-
#on_message(data) ⇒ Object
This method is called whenever data is received from the IO.
-
#on_open ⇒ Object
This method is called whenever the Protocol is initialized - i.e.: a new connection is established or an old connection switches to this protocol.
-
#on_shutdown ⇒ Object
This method is called when the server’s shutdown process had started and BEFORE the Protocol’s IO is closed.
-
#ping ⇒ Object
This method is called whenever a timeout has occurred.
-
#read(size = 2_097_152) ⇒ Object
reads from the IO up to the specified number of bytes (defaults to ~2Mb).
-
#set_timeout(seconds) ⇒ Object
Sets the timeout in seconds for IO activity (set timeout within #on_open).
-
#ssl? ⇒ Boolean
returns true if the protocol is using an encrypted connection (the IO is an OpenSSL::SSL::SSLSocket).
-
#timeout?(time) ⇒ Boolean
This method is used by Iodine to ask whether a timeout has occured.
-
#write(data) ⇒ Object
this method, writes data to the socket / io object.
Constructor Details
#initialize(io) ⇒ Protocol
This method is used by Iodine to initialized the Protocol.
A new Protocol instance set itself up as the IO’s protocol (replacing any previous protocol).
Normally you won’t need to override this method. Override #on_open instead.
134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/iodine/protocol.rb', line 134 def initialize io @timeout ||= nil @send_locker = Mutex.new @locker = Mutex.new @io = io touch @locker.synchronize do Iodine.switch_protocol @io.to_io, self on_open end end |
Instance Attribute Details
Class Method Details
Instance Method Details
#call ⇒ Object
Called by Iodine whenever there is data in the IO’s read buffer.
Normally you won’t need to override this method. Override #on_message instead.
149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/iodine/protocol.rb', line 149 def call return unless @locker.try_lock begin data = read if data (data) data.clear end ensure @locker.unlock end end |
#close ⇒ nil Also known as: disconnect
Closes the IO object.
69 70 71 72 |
# File 'lib/iodine/protocol.rb', line 69 def close @io.close unless @io.closed? nil end |
#closed? ⇒ Boolean
74 75 76 |
# File 'lib/iodine/protocol.rb', line 74 def closed? @io.closed? end |
#id ⇒ Object
returns the connection’s unique local ID as a Hex string.
This can be used locally but not across processes.
109 110 111 |
# File 'lib/iodine/protocol.rb', line 109 def id @id ||= @io.to_io.object_id.to_s(16) end |
#on_close ⇒ Object
This method is called AFTER the Protocol’s IO is closed - it will only be called once.
44 45 |
# File 'lib/iodine/protocol.rb', line 44 def on_close end |
#on_message(data) ⇒ Object
This method is called whenever data is received from the IO.
40 41 |
# File 'lib/iodine/protocol.rb', line 40 def data end |
#on_open ⇒ Object
This method is called whenever the Protocol is initialized - i.e.: a new connection is established or an old connection switches to this protocol.
37 38 |
# File 'lib/iodine/protocol.rb', line 37 def on_open end |
#on_shutdown ⇒ Object
This method is called when the server’s shutdown process had started and BEFORE the Protocol’s IO is closed. It allows graceful shutdown for network protocols.
48 49 |
# File 'lib/iodine/protocol.rb', line 48 def on_shutdown end |
#ping ⇒ Object
This method is called whenever a timeout has occurred. Either implement a ping or close the connection. The default implementation closes the connection unless the protocol is still processing information received before timeout occurred.
53 54 55 |
# File 'lib/iodine/protocol.rb', line 53 def ping @locker.locked? ? touch : close end |
#read(size = 2_097_152) ⇒ Object
reads from the IO up to the specified number of bytes (defaults to ~2Mb).
79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/iodine/protocol.rb', line 79 def read size = 2_097_152 touch ssl? ? read_ssl(size) : @io.recv_nonblock( size ) # @io.read_nonblock( size ) # this one is a bit slower... rescue OpenSSL::SSL::SSLErrorWaitReadable, IO::WaitReadable, IO::WaitWritable nil rescue IOError, Errno::ECONNRESET close rescue => e Iodine.warn "Protocol read error: #{e.class.name} #{e.} (closing connection)" close end |
#set_timeout(seconds) ⇒ Object
31 32 33 |
# File 'lib/iodine/protocol.rb', line 31 def set_timeout seconds @timeout = seconds end |
#ssl? ⇒ Boolean
returns true if the protocol is using an encrypted connection (the IO is an OpenSSL::SSL::SSLSocket).
62 63 64 |
# File 'lib/iodine/protocol.rb', line 62 def ssl? @io.is_a?(OpenSSL::SSL::SSLSocket) # io.npn_protocol end |
#timeout?(time) ⇒ Boolean
This method is used by Iodine to ask whether a timeout has occured.
Normally you won’t need to override this method. See #ping
166 167 168 |
# File 'lib/iodine/protocol.rb', line 166 def timeout? time ping if @timeout && !@send_locker.locked? && ( (time - @last_active) > @timeout ) end |
#write(data) ⇒ Object
this method, writes data to the socket / io object.
93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/iodine/protocol.rb', line 93 def write data begin @send_locker.synchronize do r = @io.write data touch r end rescue => e # Iodine.info e.message close end end |