local_message 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,42 @@
1
+ require 'socket'
2
+
3
+ class LocalMessageClient
4
+
5
+ attr_reader :server, :port, :username, :listen_port
6
+
7
+ def initialize(server_hostname, server_port, user_name)
8
+ @server = server_hostname
9
+ @port = server_port
10
+ @username = user_name
11
+ @listen_port = Random.rand(2000..30_000)
12
+ end
13
+
14
+ def register
15
+ send("@register #{username} #{listen_port}")
16
+ end
17
+
18
+ def send(message)
19
+ socket = TCPSocket.open(server, port)
20
+ sleep 1
21
+ socket.write(message)
22
+ socket.close
23
+ #puts "Waiting for server acknowledgement..."
24
+ #listen
25
+ end
26
+
27
+ def new_listen_port
28
+ @listen_port = Random.rand(1000..30_000)
29
+ end
30
+
31
+ def listen
32
+ #puts "Listening on #{listen_port}..."
33
+ server = TCPServer.open(listen_port)
34
+ client = server.accept
35
+ #puts "Connection open, waiting for message..."
36
+ message = client.read
37
+ client.close
38
+ server.close
39
+ message
40
+ end
41
+
42
+ end
@@ -0,0 +1,130 @@
1
+ require 'socket'
2
+
3
+ class LocalMessageRouter
4
+
5
+ attr_reader :port, :registered_users, :open_ports
6
+
7
+ def initialize(listening_port)
8
+ @port = listening_port
9
+ @registered_users = {}
10
+ @open_ports = []
11
+ end
12
+
13
+ def start
14
+ server = TCPServer.open(port)
15
+ begin
16
+
17
+ puts "Listening on port: #{port}..."
18
+ Thread.start(server.accept) do |client|
19
+ fam, port, hostname, ip = client.peeraddr
20
+ puts "Connection initiated from #{hostname}:#{port}"
21
+ message = client.read
22
+ puts "Message from #{hostname}:#{port}: #{message}"
23
+ puts handle(message, port, ip)
24
+ puts "Closing connection from #{hostname}:#{port}"
25
+ client.close
26
+ end
27
+
28
+ end while true
29
+ end
30
+
31
+ def handle(message, port, ip)
32
+ if register?(message)
33
+ username, port = strip_username_port(message)
34
+ register(username, port.to_i, ip)
35
+ if registered?(username)
36
+ puts "Registered #{username} => #{ip}:#{port}"
37
+ else
38
+ puts "Couldn't register #{username}"
39
+ end
40
+ #send_register_ack(ip, port, username)
41
+ elsif has_recipient?(message)
42
+ recipient = strip_recipient(message)
43
+ sender = username_by_ip(ip)
44
+ forward_message(sender, recipient, message)
45
+ if registered?(recipient)
46
+ #send_ack(ip, port, recipient, message)
47
+ else
48
+ #send_ack(ip, port, recipient, "No such recipient")
49
+ end
50
+ else
51
+ "Message not handled"
52
+ end
53
+ end
54
+
55
+ def register?(message)
56
+ return true if /@register/.match(message)
57
+ false
58
+ end
59
+
60
+ def registered?(username)
61
+ registered_users.has_key?(username)
62
+ end
63
+
64
+ def register(username, port, ip)
65
+ registered_users[username] = LocalMessageUser.new(port, ip)
66
+ end
67
+
68
+ def send_register_ack(hostname, port, username)
69
+ if registered?(username)
70
+ send(hostname, port, "Successfully registered #{username}")
71
+ "Successfully registered #{username}"
72
+ else
73
+ send(hostname, port, "Failed to register #{username}")
74
+ "Failed to register #{username}"
75
+ end
76
+ end
77
+
78
+ def username_by_ip(ip)
79
+ registered_users.values.each do |user|
80
+ return registered_users.key(user) if user.hostname == ip
81
+ end
82
+ end
83
+
84
+ def strip_username_port(message)
85
+ /@register\s+(.+)\s+(\d+)/.match(message)
86
+ [$1, $2]
87
+ end
88
+
89
+ def has_recipient?(message)
90
+ return true if /(@.+)\s+/.match(message)
91
+ false
92
+ end
93
+
94
+ def strip_recipient(message)
95
+ message.split[0].slice(1..-1)
96
+ end
97
+
98
+ def strip_message(message)
99
+ message.split[1..-1].join(" ")
100
+ end
101
+
102
+ def forward_message(sender, recipient, message)
103
+ if registered?(recipient)
104
+ info = registered_users[recipient]
105
+ message_with_sender = "@#{sender} #{strip_message(message)}"
106
+ puts "Sending message to #{recipient}, host: #{info.hostname} port: #{info.port}"
107
+ send(info.hostname, info.port, message_with_sender)
108
+ end
109
+ end
110
+
111
+ def port_open?(port)
112
+ open_ports.include?(port)
113
+ end
114
+
115
+ def send(hostname, port, message)
116
+ Thread.new do
117
+ puts "Sending #{message} to #{hostname}:#{port}"
118
+ socket = TCPSocket.open(hostname, port)
119
+ sleep 1
120
+ socket.write(message)
121
+ socket.close
122
+ end
123
+ end
124
+
125
+ def send_ack(hostname, port, recipient, message)
126
+ send(hostname, port, "Sent #{message} to #{recipient}")
127
+ "Sent #{message} to #{hostname}:#{port}"
128
+ end
129
+
130
+ end
@@ -0,0 +1,22 @@
1
+ class LocalMessageUser
2
+
3
+ attr_reader :port, :hostname
4
+
5
+ def initialize(port_number, host_name)
6
+ @port = port_number
7
+ @hostname = host_name
8
+ end
9
+
10
+ def ==(other)
11
+ hostname == other.hostname
12
+ end
13
+
14
+ def eql?(other)
15
+ self == other
16
+ end
17
+
18
+ def hash
19
+ hostname.hash
20
+ end
21
+
22
+ end
@@ -0,0 +1,3 @@
1
+ require 'local_message/local_message_router'
2
+ require 'local_message/local_message_client'
3
+ require 'local_message/local_message_user'
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: local_message
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Elliot Shiu
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-06 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Routes messages across a local network.
15
+ email: elliot@sandbochs.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/local_message.rb
21
+ - lib/local_message/local_message_router.rb
22
+ - lib/local_message/local_message_client.rb
23
+ - lib/local_message/local_message_user.rb
24
+ homepage: http://www.github.com/sandbochs
25
+ licenses: []
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 1.8.24
45
+ signing_key:
46
+ specification_version: 3
47
+ summary: A message router and client.
48
+ test_files: []