Jump to content

  • Log in with Facebook Log in with Twitter Log In with Google Log In with Steam Sign In
  • Create Account
Photo

using luasocket in a luascript

- - - - -

  • Please log in to reply
26 replies to this topic

#21
OFFLINE   belstgut

belstgut

    Member

  • Members
  • PipPip
  • 32 posts
4
A step in the right direction
  • LocationMering, Germany

So I got everything working now.

 

One problem though,

 

using luasocket http is blocking.

 

Since I am using this in et_clientConnect (not always though) everytime I do the http request the server lags until the request has finished. I return nil or a string based on the result of the request.

 

Is there any way I could make this callback nonblocking? (like let it execute for more than 1 server frame, the client has to wait for the result though)?



#22
OFFLINE   gaoesa

gaoesa

    Advanced Member

  • Management
  • PipPipPipPip
  • 4391 posts
341
Will become famous
  • LocationFinland

I don't think so. The mod and the Lua execute in the same thread. So the et_clientConnect must return for the game to continue and the return value is also used by the game. If you can find a way to create threads within the Lua and have a separate thread for the networking, you might get by with less lags. Of course, you still have synchronization issues.



#23
OFFLINE   belstgut

belstgut

    Member

  • Members
  • PipPip
  • 32 posts
4
A step in the right direction
  • LocationMering, Germany

having threads in lua should not be a problem, since u can just bind a C module anyway.

 

But I would like to return a ~= nil value based on the result of the request in the et_ClientConnect callback.  how would I do that? I mean even if I fork the networking into a seperate thread, the function would still have to wait for that thread to finish, so I could return sth. I almost think that this would not be possible.

 

So probably just always return nil and then kick based on the result.

 

Still, this could be done more beautifully like calling every callback in its own thread and collecting the return values in an array. when all callbacks are finished, iterate over the results instead of calling the callbacks in a loop.


Edited by belstgut, 27 June 2016 - 09:24 AM.


#24
OFFLINE   gaoesa

gaoesa

    Advanced Member

  • Management
  • PipPipPipPip
  • 4391 posts
341
Will become famous
  • LocationFinland

The return value is used by the game so the game is stuck waiting for it in every case. Adding threading is not something that should be ever done lightly, without considering if there is something wrong in the design that can be fixed to avoid adding threads, especially in this case when it wouldn't change anything in the game. I don't remember, but probably there is only one callback made on client connect, so there aren't even parallel callbacks to be made. On the other hand, you can kick players at any time using Lua.



#25
OFFLINE   belstgut

belstgut

    Member

  • Members
  • PipPip
  • 32 posts
4
A step in the right direction
  • LocationMering, Germany

sure there are more callbacks. I mean every lua script which has the et_ClientConnect function gets called when a player connects.



#26
OFFLINE   gaoesa

gaoesa

    Advanced Member

  • Management
  • PipPipPipPip
  • 4391 posts
341
Will become famous
  • LocationFinland

In that way, yes there can be several parallel calls to it. It's still wrong to address it with threading. Furthermore, every one core VPS out there would suffer even more performance degradation coming from multiple context switches and added synchronization. Do also note, that every call made from the scripts to the game, would need added work also, to make them safe to use. Even on multiple cores, the result in this case would reduce performance, when the same player and same data is handled in multiple threads, which would mean that even the parallel threads would end up synchronizing accesses and validating the data at every possible moment. It's just a plain bad idea.



#27
OFFLINE   belstgut

belstgut

    Member

  • Members
  • PipPip
  • 32 posts
4
A step in the right direction
  • LocationMering, Germany

Since I got this running now, I wanted to share on how to do it.

 

u need https://github.com/s...xamples/sofix.c compiled as shared Object with

-DMOON_DLFIX_LIBNAME=/path/to/silent/qagame.mp.i386.so

 

example: gcc -DMOON_DLFIX_LIBNAME='"/home/gs/wolfet/silent/qagame.mp.i386.so"' -m32 -Wall -Wextra -I.. -fpic -shared -Os -o sofix.so sofix.c

 

Luasocket (precompiled for 32bit): https://ptpb.pw/gyb_.zip

 

Copas: https://github.com/k...tree/master/src

 

copy/extract luasocket, sofix.so and copas to: silent/lualibs/

 

after that create your luamodule. example:

require('sofix') -- needs to be required before any other C based module

local copas = require('copas')
local asynchttp = require('copas.http').request

-- random callback
-- makes http request at every player connect (probably not what u wanna do)
function et_ClientConnect(clientNum, firstTime, isBot)
    copas.addthread(function()
        local body, c, h = asynchttp('http://example.org/')
        if c ~= 200 then
            et.G_LogPrint(("HTTP Error: %d"):format(c))
            return
        end
        -- use body and headers here. eg:
        et.G_LogPrint(body)
    end)
end

-- "Using gameloop as event loop"
function et_RunFrame(levelTime)
    if levelTime % 500 ~= 0 then
        return
    end
    copas.step()
end

I am currently using a structure like that and haven't experienced any lags till now.






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users