问题描述
在 Rails 中,集成 UDP 侦听过程以更新模型的某些元素(特别是它将向其中一个表添加行)的最佳方式是什么.
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).
简单的答案似乎是在同一个进程中使用 UDP 套接字对象启动一个线程,但不清楚我什至应该在哪里执行符合 rails 方式的操作.有没有一种巧妙的方法来开始监听 UDP?具体来说,我希望能够编写一个 UDPController 并在每个数据报消息上调用一个特定的方法.理想情况下,我希望避免在 UDP 上使用 HTTP(因为它会浪费一些在这种情况下非常宝贵的空间),但我完全可以控制消息格式,因此我可以向 Rails 提供它需要的任何信息.
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.
推荐答案
让我来介绍一下 TCP.UDP 是一种将数据包扔到风中"的协议,它不提供任何可靠性.例如,它可用于 IP 语音,其中可以接受奇数丢弃的数据包.通过使用 TCP 套接字,您仍然可以避免使用 HTTP,而且 TCP 堆栈将处理重试和等等.
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.
由inetd 启动的TCP 服务器是世界上最简单的事情:你编写一个程序,从stdin 读取并写入stdout,然后告诉inetd 在某个端口收到请求时运行该程序.您无需编写任何网络代码.
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.
这是一个简单的 inetd tcp 服务器:
Here's a simple inetd tcp server:
#!/usr/bin/ruby1.8
input = gets
puts "You said: #{input}"
下面是告诉 inetd 运行它的方法:
Here's how to tell inetd to run it:
1024 stream tcp nowait wconrad /tmp/tcpserver.rb
这意味着侦听端口 1024 上的 tcp 连接.当它们发生时,以用户 wconrad 启动/tmp/tcpserver.rb.man inetd.conf
了解更多信息.
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.
你可以用telnet测试一下:
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
只是为了表明 Ruby 中的 tcp 服务器很简单:
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
由于 TCP 如此简单,您需要一个令人信服的理由来打扰 UDP.
With TCP being so easy, you need a compelling reason to bother with UDP.
这篇关于Rails 是否支持一种简洁的监听 UDP 套接字的方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!