In Rails what would be the best way of integrating a UDP listening process that updated certain elements of the model (specifically its going to be adding rows to one of the tables).
The simple answer seems to be start a thread with the UDP socket object within the same process, but its not clear quite where I should even do that which fits with the rails way. Is there a neat way to start listening to UDP? Specifically I'd love to be able to write a UDPController and have a particular method called on each Datagram message. Ideally I would want to avoid using HTTP over UDP (as it would waste some of what in this case is very precious space) but I am fully in control of the message format so I can provide Rails with any information it would need.
Rails is a web application framework, not a server daemon framework. Unless you know of a web server that passes UDP packets, I imagine you would have to write and run a separate process and either have it talk to your Rails app via HTTP or just manipulate the database directly.
Let me make a pitch for TCP. UDP is a "throw the packet to the wind" protocol which provides no reliability. It finds uses in, for example, voice over IP where the odd dropped packet is acceptable. By using a TCP socket, you can still avoiding using HTTP, plus TCP stack will handle retries & etc. for you.
A TCP server which is launched by inetd is the simplest thing in the world: you write a program that reads from stdin and writes to stdout, then tell inetd to run that program whenever requests come in on a certain port. You won't have to write any network code.
Here's a simple inetd tcp server:
#!/usr/bin/ruby1.8
input = gets
puts "You said: #{input}"
Here's how to tell inetd to run it:
1024 stream tcp nowait wconrad /tmp/tcpserver.rb
This means to listen for tcp connections on port 1024. When they occur, launch /tmp/tcpserver.rb as user wconrad. man inetd.conf
for more information.
You can test it with telnet:
$ telnet localhost 1024
Trying 127.0.0.1...
Connected to ceres.
Escape character is '^]'.
Howdy!
You said: Howdy!
Connection closed by foreign host.
$
Or you can use a simple client:
$ cat /tmp/tcpclient.rb
#!/usr/bin/ruby1.8
require 'socket'
t = TCPSocket.new('localhost', 1024)
t.puts "Hello"
t.close_write
puts t.read
t.close
$ /tmp/tcpclient.rb
You said: Hello
and just to show that tcp servers in Ruby are easy:
!/usr/bin/ruby1.8
require 'socket'
def handle_session(socket)
s = socket.gets
socket.puts "You said: #{s}"
socket.close
end
server = TCPServer.new('localhost', 1024)
while (session = server.accept)
Thread.new do
handle_session(session)
end
end
With TCP being so easy, you need a compelling reason to bother with UDP.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With