Lua 套接字 - 异步事件 [英] Lua sockets - Asynchronous Events

查看:29
本文介绍了Lua 套接字 - 异步事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在当前的 lua 套接字实现中,我看到我们必须安装一个定期回调的计时器,以便我们检查非阻塞 API 以查看是否收到任何东西.

In current lua sockets implementation, I see that we have to install a timer that calls back periodically so that we check in a non blocking API to see if we have received anything.

这一切都很好,但是在 UDP 的情况下,如果发送方要发送大量信息,我们是否有丢失数据的风险.假设另一台设备通过 UDP 发送一张 2MB 的照片,我们每 100 毫秒检查一次套接字接收.在 2MBps 时,底层系统必须在我们的调用查询底层 TCP 堆栈之前存储 200Kbits.

This is all good and well however in UDP case, if the sender has a lot of info being sent, do we risk loosing the data. Say another device sends a 2MB photo via UDP and we check socket receive every 100msec. At 2MBps, the underlying system must store 200Kbits before our call queries the underlying TCP stack.

当我们在特定套接字上接收数据而不是我们现在必须进行的轮询时,有没有办法触发事件?

Is there a way to get an event fired when we receive the data on the particular socket instead of the polling we have to do now?

推荐答案

处理这个问题的方法有很多种;你会选择哪一个取决于你想做多少工作.*

There are a various ways of handling this issue; which one you will select depends on how much work you want to do.*

但首先,您应该(对自己)澄清您是在处理 UDP 还是 TCP;UDP 套接字没有底层 TCP 堆栈".此外,UDP 是用于发送整个数据(例如文本或照片)的错误协议;这是一个不可靠的协议,因此您不能保证收到每个数据包,除非您使用托管套接字库(例如 ENet).

But first, you should clarify (to yourself) whether you are dealing with UDP or TCP; there is no "underlying TCP stack" for UDP sockets. Also, UDP is the wrong protocol to use for sending whole data such as a text, or a photo; it is an unreliable protocol so you aren't guaranteed to receive every packet, unless you're using a managed socket library (such as ENet).

轮询是唯一的方法.

  • 阻塞:不带时间参数调用 socket.select 并等待套接字可读.
  • 非阻塞:使用0的超时参数调用socket.select,并在socket上使用sock:settimeout(0)你正在阅读.
  • Blocking: call socket.select with no time argument and wait for the socket to be readable.
  • Non-blocking: call socket.select with a timeout argument of 0, and use sock:settimeout(0) on the socket you're reading from.

然后简单地重复调用这些.我建议对非阻塞版本使用 协程调度程序,以允许程序的其他部分继续执行时不会造成太多延迟.

Then simply call these repeatedly. I would suggest using a coroutine scheduler for the non-blocking version, to allow other parts of the program to continue executing without causing too much delay.

与上面的方法相同,但是socket存在于另一个lane中(另一个线程中的轻量级Lua状态)使用Lua 车道(最新源).这允许您立即从套接字读取数据并放入缓冲区.然后,你使用一个 linda 将数据发送到主线程进行处理.

Same as the above method, but the socket exists in another lane (a lightweight Lua state in another thread) made using Lua Lanes (latest source). This allows you to instantly read the data from the socket and into a buffer. Then, you use a linda to send the data to the main thread for processing.

这可能是您问题的最佳解决方案.

This is probably the best solution to your problem.

我为此做了一个简单的例子,可在这里获得.它依赖于 Lua Lanes 3.4.0(GitHub repo)和一个修补的 LuaSocket 2.0.2(GitHub repo)="http://luarocks.org/repositories/rocks/#luasocket" rel="noreferrer">来源,补丁, 博客文章重新'补丁)

I've made a simple example of this, available here. It relies on Lua Lanes 3.4.0 (GitHub repo) and a patched LuaSocket 2.0.2 (source, patch, blog post re' patch)

结果很有希望,但如果您从中派生出来,您绝对应该重构我的示例代码.

The results are promising, though you should definitely refactor my example code if you derive from it.

如果你有点受虐狂,你可以尝试从头开始实现一个套接字库.LuaJITFFI 库 使这成为可能来自纯 Lua.Lua Lanes 对此也很有用.

If you're a little masochistic, you can try implementing a socket library from scratch. LuaJIT's FFI library makes this possible from pure Lua. Lua Lanes would be useful for this as well.

对于 Windows,我建议查看 William Adam 的博客.他在 LuaJIT 和 Windows 开发方面有过一些非常有趣的冒险经历.Linux等看C的教程或者LuaSocket的源码,翻译成LuaJIT FFI操作.

For Windows, I suggest taking a look at William Adam's blog. He's had some very interesting adventures with LuaJIT and Windows development. As for Linux and the rest, look at tutorials for C or the source of LuaSocket and translate them to LuaJIT FFI operations.

(如果 API 需要,LuaJIT 支持 回调;但是,有显着的性能成本与从 Lua 到 C 的轮询相比.)

(LuaJIT supports callbacks if the API requires it; however, there is a signficant performance cost compared to polling from Lua to C.)

ENet 是一个很棒的图书馆.它提供了 TCP 和 UDP 之间的完美组合:需要时可靠,否则不可靠.它还抽象了操作系统特定的细节,就像 LuaSocket 所做的那样.可以使用Lua API绑定,也可以直接通过LuaJIT的FFI访问(推荐).

ENet is a great library. It provides the perfect mix between TCP and UDP: reliable when desired, unreliable otherwise. It also abstracts operating system specific details, much like LuaSocket does. You can use the Lua API to bind it, or directly access it via LuaJIT's FFI (recommended).

* 双关语无意.

* Pun unintentional.

这篇关于Lua 套接字 - 异步事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆