如何检查非阻塞 Luasocket 客户端是否断开连接?

我正在为 OBS 编写 Lua 脚本,通过 TCP 连接持续地接收来自 ProPresenter(另一个程序) 的数据。我使用 LuaSocket 库建立连接,并成功地获得了数据。

问题是,当我关闭 ProPresenter 时,我的脚本无法注册连接已关闭,即使我将 luasocket 超时设置为 0(以使它成为非阻塞连接)。我需要脚本始终处于非阻塞状态,否则它将导致 OBS 卡死并且帧率降至 1 以下...

然而,如果我将超时设置为 1 秒,Luasocket 就能够成功地注册连接已关闭,而且根据 这里 的示例,在超时为 0 时也应该能够工作。但是显然它没有,我怀疑是因为该示例使用了较旧的 Luasocket 版本,并且最新版本可能已更改。

这是我的代码:

由于超时而无法注册连接已关闭:

function recv_and_process_data()
    local data

    data, err, partial = s:receive()

    if data ~= nil then
        --处理接收到的数据。这部分起作用。
    elseif err == "closed" then
        --由于超时,无法到达这里...
        --通知脚本连接已关闭
    elseif err == "timeout" then
        --一旦关闭 ProPresenter,就会到这里
        print(err .. " 偏移量:" .. partial)
    end
end

可以注册连接关闭,但会导致 OBS 停滞不前:

function recv_and_process_data()
    local data

    s:settimeout(1) --将超时设置为 1 秒
    data, err, partial = s:receive()
    s:settimeout(0)

    if data ~= nil then
        --处理接收到的数据。这部分起作用。
    elseif err == "closed" then
        --当关闭 ProPresenter 时,将转到此处
        --通知脚本连接已关闭
    elseif err == "timeout" then
        print(err .. " 偏移量:" .. partial)
    end
end

这也不起作用(建议 在此处):

function recv_and_process_data()
    local data

    data, err, partial = s:receive(0)
    if err == "closed" then
        print(err .. " 偏移量:" .. partial)
    end
end

如果我无法让其工作,我想我得尝试重新连接以验证 ProPresenter 的服务器是否仍在运行。

点赞
用户11086022
用户11086022

我也在努力解决这个问题。我发现使用非常小的settimeout() 值仍然会返回一个错误,但它并不会阻碍程序的运行。

我使用 local Data, Error = Client:settimeout(0.0001)

2019-02-19 17:57:25