udp - 使用 Crystal/Kemal 监听 UDP 数据包

标签 udp crystal-lang kemal

我一直在尝试使用 Crystal 和 Kemal 创建一个非阻塞服务器,它将 (a) 监听发送给它的 UDP 消息流,然后 (b) 然后将该消息转发到 WebSocket 到任何已启动的浏览器ws 连接。

到目前为止,我能管理的最好的是:

require "kemal"
require "socket"

server = UDPSocket.new
server.bind "localhost", 1234
puts "Started..."

ws "/" do |socket|

    udp_working = true

    while udp_working
        message, client_addr = server.receive
        socket.send message
    end

    socket.on_close do
        puts "Goodbye..."
        udp_working = false
    end
end

这一切似乎有点不雅,而且确实没有按预期工作,因为:
  • 在正在启动的 Crystal 服务器和连接到 Crystal 服务器的第一个 Web 浏览器之间发送的所有 UDP 数据包都被缓存并发送到一个巨大的积压中
  • 浏览器从 WebSockets 断开连接没有得到正确处理,即 socket.on_close 没有被触发,循环继续直到我终止 Crystal 服务器

  • 我希望有一个 server.on_message 类型的处理,它可以让我只在收到 UDP 数据包时运行代码,而不是阻止服务器的持续轮询。是否有另一种方法可以使用 Crystal/Kemal 实现这一目标?

    谢谢!

    最佳答案

    你的方法有几个问题:

    一、socket.on_close无法工作,因为这条线永远不会到达。只要 udp_working == true,while 循环就会运行它只会设置为 falseon_close钩。

    如果您不希望 UDP 数据报堆积,那么您需要从一开始就接收它们,并在没有连接 websocket 的情况下做任何您想做的事情(也许处理?)。没有on_message Hook UDPServer但是 receive已经是非阻塞的。所以你可以在一个循环中运行它(在它自己的光纤中)并在方法返回时采取行动。见 Crystal Concurrency详情;还有一个使用 TCPSocket 的例子,但 UDP 在这方面应该是类似的。

    关于udp - 使用 Crystal/Kemal 监听 UDP 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46805654/

    相关文章:

    crystal-lang - 为什么数组 "each"在 Crystal 1.3.0 中不再工作?我应该用什么代替?

    crystal-lang - Lucky Framework 的查询接口(interface)

    crystal-lang - 在生产模式下启动 Crystal

    concurrency - 在没有 IO 的光纤之间循环

    c++ - 开放框架/C++/Arduino : UDP SendAll fails at 1473 chars

    sockets - UDP 套接字客户端无法与 Minikube 上的 UDP 套接字服务器通信

    c++ - 通过 Win32 应用程序从 C/C++ 中的 UDP 端口读取

    python - 如何在 Python 包/扩展中使用 Crystal?

    java - 无法通过广播地址接收 UDP 数据包,ArtNet