Class: NetworkFacade::Base::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/network-facade/base.rb

Direct Known Subclasses

TCP::Server, Unix::Server

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Server

Returns a new instance of Server.



99
100
101
102
103
104
# File 'lib/network-facade/base.rb', line 99

def initialize(options = {})
	@options = options
	require 'zlib' if @options[:compress]
	@fd = [@options[:server]]
	@objs = {}
end

Instance Method Details

#acceptObject



106
107
108
109
# File 'lib/network-facade/base.rb', line 106

def accept
	NetworkFacade.log(:info, "Accepting new client")
	raise "Default Server#accept method"
end

#add(obj) ⇒ Object



111
112
113
114
115
116
# File 'lib/network-facade/base.rb', line 111

def add(obj)
	id = obj.class.name.downcase
	NetworkFacade.log(:info, "Adding new object #{obj.inspect} at /#{id}")
	@objs[id] = obj
	self
end

#client_id(client) ⇒ Object



118
119
120
# File 'lib/network-facade/base.rb', line 118

def client_id(client)
	"0x%08x" % client.object_id
end

#read(client) ⇒ Object

Raises:

  • (EOFError)


165
166
167
168
169
170
171
172
173
# File 'lib/network-facade/base.rb', line 165

def read(client)
	size = client.read(4)
	raise EOFError if size.nil?
	size = size.unpack('N').first
	NetworkFacade.log(:debug, "Read #{size + 4} bytes", client_id(client))
	data = client.read(size)
	data = Zlib::Inflate.inflate(data) if @options[:compress]
	Marshal.load(data)
end

#startObject



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/network-facade/base.rb', line 122

def start
	loop do
		readable, writable, errors, timeout = IO.select(@fd)
		begin
			if readable.include?(@options[:server])
				accept
				readable.delete(@options[:server])
			end
		rescue Exception
			NetworkFacade.log(:warn, "An error occured when accapting new client")
			NetworkFacade.log(:warn, $!)
			next
		end

		readable.each do |client|
			size = nil
			data = nil
			begin
				data = read(client)
				result = nil
				begin
					if @objs[data[0]].respond_to? data[1]
						NetworkFacade.log(:info, "Call method #{data[1].inspect} with #{data[2].inspect}", client_id(client))
						result = @objs[data[0]].send(data[1], *data[2])
					else
						NetworkFacade.log(:info, "Call unknown method #{data[1].inspect}", client_id(client))
					end
				rescue Exception
					result = $!
					NetworkFacade.log(:info, "Error occured when executing #{data[1].inspect} with #{data[2].inspect}", client_id(client))
					NetworkFacade.log(:info, $!)
				end
				write(client, result)
			rescue Exception
				NetworkFacade.log(:info, "Close connection", client_id(client))
				client.close
				@fd.delete(client)
				GC.start
			end
		end
	end
end

#write(client, data) ⇒ Object



175
176
177
178
179
180
181
182
# File 'lib/network-facade/base.rb', line 175

def write(client, data)
	data = Marshal.dump(data)
	data = Zlib::Deflate.deflate(data, Zlib::FINISH) if @options[:compress]
	NetworkFacade.log(:debug, "Write #{data.size + 4} bytes", client_id(client))
	client.write([data.size].pack('N'))
	client.write(data)
	client.flush
end