1

我正在 Lua 中实现套接字,我正在使用的示例代码使用以下方法来保持连接处于活动状态:

while true do
  -- handle socket traffic here
  socket.sleep(1)
end

循环显然阻止了项目代码的其余部分运行,但如果我退出循环,套接字服务器会立即表示连接已关闭。

那么如何在我的 Lua 代码的其余部分正常运行时同时保持套接字打开?(是否有某种后台作业支持?协程可以用于此目的吗?)

4

4 回答 4

0

正如你所说,我使用 Lua Lanes 启动了一个正在执行套接字 i/o 并在后台运行的线程。

http://kotisivu.dnainternet.net/askok/bin/lanes/

看看这个答案,它提供了有关使用 Lua 通道和套接字的信息。

LuaLanes 和 LuaSockets

那里提供的双线程轮询解决方案可能是最可行的,但是那里也有关于协程的信息。

于 2013-02-23T23:48:26.133 回答
0

(您的问题与此问题相似(并且我已将其适当地标记为重复),但为方便起见,这是我的答案的副本!)

有多种方法可以处理此问题;你会选择哪一个取决于你想做多少工作。*

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

Lua51/LuaJIT + LuaSocket

轮询是唯一的方法。

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

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

Lua51/LuaJIT + LuaSocket + Lua Lanes(推荐)

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

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

我已经做了一个简单的例子,可以在这里找到。它依赖于 Lua Lanes 3.4.0 ( GitHub repo ) 和修补过的 LuaSocket 2.0.2 ( source , patch , blog post re' patch )

结果是有希望的,但如果你从中派生出我的示例代码,你肯定应该重构它。

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

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

对于 Windows,我建议查看William Adam 的博客。他在 LuaJIT 和 Windows 开发方面有过一些非常有趣的冒险经历。至于 Linux 和其他,请查看 C 教程或 LuaSocket 的源代码,并将它们转换为 LuaJIT FFI 操作。

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

LuaJIT + ENet

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

*双关语无意。

于 2013-02-24T10:12:46.670 回答
0

其他答案很好,但有点错过这里最重要的一点:

现在很少需要在处理套接字时使用线程

为什么?因为多个套接字是如此普遍,所以操作系统(尤其是 *ix 系统)以epoll函数的形式实现了“多轮询”。

ZeroMQ 等所有高性能网络库都只保留几个线程,并在其中运行。这降低了内存要求,但不会牺牲速度。

所以我的建议是直接连接到 OS 库,这在 Lua中非常容易。您不必自己编写代码 - 快速 google 搜索给我带来了这个 epoll 包装器[1] 然后您仍然可以使用协程仅从实际有一些数据的套接字中读取。

您可能还想看看ZeroMQ 库本身

[1] Neopallium为 ZMQ 创建了 Lua 绑定,所以我认为它是合法的。

于 2013-02-24T10:23:52.257 回答
0

您确实可以为此目的使用协程。这就是流行的库Copas所做的。

根据您的用例,您可以使用 Copas 或查看其源代码以了解它是如何工作的。您还可以查看使用 Copas的lua-websockets 。

于 2013-02-25T10:56:20.967 回答