Search code examples
tcplualuasocket

How to check if a nonblocking luasocket client has lost it's connection?


I'm writing a Lua-script for OBS, that continually recieves data from ProPresenter(another program) over a TCP connection. I use the LuaSocket library to make the connection, and i get the data as expected.

The problem is that when i close ProPresenter i can't get my script to register that the connection is closed, while i set the luasocket timeout to 0 (for it to be a nonblocking connection). I need the script to be nonblocking at all times, or else it will cause all of OBS to stall and the framerate to drop below 1...

However, if i set the timeout to eg. 1 second, luasocket registers that the connection is closed without trouble, and according to this example it should work when timeout is 0 as well. But apparently it doesn't, and i suspect it is because the example uses an older wersion of Luasocket, and that the newest version might have changed.

Here is my code:

Doesn't register that the connection has closed duo to timeout:

function recv_and_process_data()
    local data 

    data, err, partial = s:receive()

    if data ~= nil then
        --process the recieved data. This part works.
    elseif err == "closed" then
        --doesn't get here because of timeout...
        --inform script that the connection has closed
    elseif err == "timeout" then
        --goes here as soon as ProPresenter is closed
        print(err .. " partial: " .. partial) 
    end
end

Registers when the connection closes, but makes OBS stall:

function recv_and_process_data()
    local data 

    s:settimeout(1) --timeout set to 1 second
    data, err, partial = s:receive()
    s:settimeout(0)

    if data ~= nil then
        --process the recieved data. This part works.
    elseif err == "closed" then
        --goes here when ProPresenter is closed
        --inform script that the connection has closed
    elseif err == "timeout" then
        print(err .. " partial: " .. partial)
    end
end

This doesn't work either (as suggestet here):

function recv_and_process_data()
    local data 

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

If i can't get this working i guess i have to try and reconnect to see if ProPresenters server is still running.


Solution

  • I was trying to figure out this problem too. I found that a very small settimeout() value still returns an error you can use but doesn't hold the program up at all.

    I use local Data, Error = Client:settimeout(0.0001)