【问题标题】:Does Rails support a neat way of listening to a UDP socket?Rails 是否支持一种简洁的监听 UDP 套接字的方式?
【发布时间】:2010-12-30 08:52:38
【问题描述】:

在 Rails 中,集成 UDP 侦听过程以更新模型的某些元素(特别是它将向其中一个表添加行)的最佳方式是什么。

简单的答案似乎是在同一个进程中使用 UDP 套接字对象启动一个线程,但不清楚我什至应该在哪里执行符合 rails 方式的操作。有没有一种巧妙的方法来开始监听 UDP?具体来说,我希望能够编写一个 UDPController 并在每个数据报消息上调用一个特定的方法。理想情况下,我希望避免在 UDP 上使用 HTTP(因为它会浪费一些在这种情况下非常宝贵的空间),但我完全可以控制消息格式,因此我可以为 Rails 提供它需要的任何信息。

【问题讨论】:

  • 我的需求几乎相同。你有满意的解决方案吗?

标签: ruby-on-rails ruby sockets udp


【解决方案1】:

Rails 是一个 Web 应用程序框架,而不是一个服务器守护程序框架。除非您知道一个传递 UDP 数据包的 Web 服务器,否则我想您将不得不编写并运行一个单独的进程,或者让它通过 HTTP 与您的 Rails 应用程序通信,或者直接操作数据库。

【讨论】:

    【解决方案2】:

    让我来介绍一下 TCP。 UDP 是一种“将数据包扔到风中”的协议,它不提供任何可靠性。例如,它可用于 IP 语音,其中可以接受奇数丢弃的数据包。通过使用 TCP 套接字,您仍然可以避免使用 HTTP,而且 TCP 堆栈会为您处理重试等。

    由inetd 启动的TCP 服务器是世界上最简单的事情:您编写一个程序,从stdin 读取并写入stdout,然后告诉inetd 在某个端口收到请求时运行该程序。您无需编写任何网络代码。

    这是一个简单的 inetd tcp 服务器:

    #!/usr/bin/ruby1.8
    
    input = gets
    puts "You said: #{input}"
    

    下面是告诉 inetd 运行它的方法:

    1024            stream  tcp     nowait    wconrad /tmp/tcpserver.rb
    

    这意味着侦听端口 1024 上的 tcp 连接。当它们发生时,以用户 wconrad 启动 /tmp/tcpserver.rb。 man inetd.conf 了解更多信息。

    你可以用telnet测试一下:

    $ telnet localhost 1024
    Trying 127.0.0.1...
    Connected to ceres.
    Escape character is '^]'.
    Howdy!
    You said: Howdy!
    Connection closed by foreign host.
    $
    

    或者你可以使用一个简单的客户端:

    $ 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 服务器很简单:

    !/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。

    【讨论】:

    • 否决了这个答案,因为它无法回答标题中的问题。虽然这个答案可能已经满足了最初的提问者,但假设没有人会关心使用 UDP 并在答案中完全无视它只是因为“你需要一个令人信服的理由来打扰 UDP”,这是可耻的。使用 UDP 有很多有用的理由,因为如果应用程序不需要可靠性,它会消除 TCP 带来的大量开销。
    • @JeffDavenport 感谢您对您的否决票的良好解释。解释否决票是良好的公民身份,非常感谢。至少有一次,SO允许横向“你应该考虑这样做”的答案;这个答案是当时写的。在我看来,UDP 在 Ruby 中不像 TCP 那样简单,所以我认为我说你需要一个充分的理由来使用 UDP 是正确的:确实有使用 UDP 的理由,但除非这些原因,否则我不会使用 UDP是必需的。
    猜你喜欢
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-06
    相关资源
    最近更新 更多