当前位置 : 主页 > 网络编程 > lua >

Lua套接字 – 异步事件

来源:互联网 收集:自由互联 发布时间:2021-06-23
在当前的lua套接字实现中,我看到我们必须安装一个定期回调的计时器,以便我们检查非阻塞API以查看是否收到了任何内容. 这一切都很好,但在UDP情况下,如果发件人发送了大量信息,我们是
在当前的lua套接字实现中,我看到我们必须安装一个定期回调的计时器,以便我们检查非阻塞API以查看是否收到了任何内容.

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

当我们收到特定套接字上的数据而不是我们现在要做的轮询时,有没有办法让事件被触发?

有各种方法来处理这个问题;您将选择哪一个取决于您想要做多少工作.*

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

Lua51 / LuaJIT LuaSocket

轮询是唯一的方法.

>阻塞:调用没有时间参数的socket.select并等待套接字可读.
>非阻塞:使用超时参数0调用socket.select,并在您正在读取的套接字上使用sock:settimeout(0).

然后简单地重复调用它们.
我建议使用coroutine scheduler作为非阻塞版本,以允许程序的其他部分继续执行而不会导致太多延迟.

Lua51 / LuaJIT LuaSocket Lua Lanes(推荐)

与上述方法相同,但套接字存在于使用Lua Lanes(latest source)制作的另一个通道(另一个线程中的轻量级Lua状态)中.这允许您立即从套接字读取数据并进入缓冲区.然后,使用linda将数据发送到主线程进行处理.

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

我已经做了一个简单的例子,可用here.它依赖于Lua Lanes 3.4.0(GitHub repo)和修补的LuaSocket 2.0.2(source,patch,blog post re’ patch)

结果很有希望,但如果你从中得到它,你肯定应该重构我的示例代码.

LuaJIT特定于操作系统的套接字

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

对于Windows,我建议看看William Adam’s blog.他有一些非常有趣的LuaJIT和Windows开发冒险.至于Linux和其他内容,请查看C的教程或LuaSocket的源代码,并将它们转换为LuaJIT FFI操作.

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

LuaJIT ENet

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

*双关语无意识.

网友评论