-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpublic_server.rb
100 lines (80 loc) · 3.66 KB
/
public_server.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
require 'socket'
require 'open-uri'
require './requests.rb'
require './arduino_client.rb'
require './public_server.rb'
require './controller.rb'
module ArduinoGateway
module Interface
# PublicServer is responsible for handling clients connections, reading client requests
# and passing on those requests to a controller for processing
class PublicServer
attr_accessor :server_running, :public_port_number
def initialize (public_port)
# initialize the port number, connection hash, and client count
@public_port_number = public_port.to_i
@connections = {}
@client_count = 0
# when debug_code variable is set to true server will print debug messages to terminal
@debug_code = true
# start public server in a block to capture any issues associated with connection.
begin
@server = TCPServer.new(@public_port_number)
@server_running = true
rescue => e
puts "[PublicServer:new] ERROR: not able to start up TCP Server #{e.message}"
end
if @debug_code; puts "[PublicServer:initialize] PublicServer initialized"; end
end
# register controller with public server; controller must include a callback method
# called register_public_request.
def register_controller(controller)
@controller = controller
end
# run the public_server; method responsible for accepting new clients, reading
# client requests and registering those requests with the controller.
def run()
unless @controller.respond_to?(:register_request)
puts "[PublicServer:run] ERROR: controller does not have register_request callback method"
return
end
if @debug_code
puts "[PublicServer:initialize] PublicServer listening to port #{@public_port_number}"
end
# while the server is accepting clients
while (client = @server.accept)
# update the client_count variable
@client_count += 1
if @debug_code; puts "[PublicServer:run] ID: #{@client_count}, new client at socket: #{client} "; end
# create a new thread to handle each incoming client request
connection = Thread.new client, @client_count do |client_connection, client_count|
Thread.current[:client] = client_connection
client_request = client_connection.recvfrom(2000)[0].chomp.to_s
@controller.register_request(client_request, client_count)
end
# add thread to the connections hash list
@connections.merge!({@client_count => connection})
end
end
# callback method used by controller to respond to client requests once data
# is received from the arduinos
def respond(response, response_id)
@connections[response_id][:client].puts response unless response.empty?
stop(response_id)
end
# method that kills client connections from @connections hash list and turns
# off server if no connection id is provided.
def stop(id = -11)
if id == -11
@server.close
@server_running = false
else
@connections[id][:client].close
@connections[id].kill
@connections.delete(id)
end
puts "[PublicServer:stop] @connections array size #{@connections.size}"
end
end
end # Interface module
end # ArduinoGateway module