Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ MUSHclient
➜ Lua
➜ Luasocket and Coroutines?
Luasocket and Coroutines?
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Posted by
| Rivius
(99 posts) Bio
|
Date
| Thu 15 Sep 2011 10:57 PM (UTC) |
Message
| I've never had the chance to use coroutines in lua, and as an amateur novice programmer, I'm not entirely sure of how they work but generally have a vague idea of the advantages from a brief talk with a friend. I've been attempting to use lua socket to pull information from a website for the purposes of finding out what organization a player is in and group them into it. The code I came up with does what is intended and works as follows:
function getorg(player)
local w = assert(http.request("http://www.ironrealms.com/game/honors/Lusternia/"..player))
if not w then
ui.alert("There has been an error retrieving information from the website.")
if IsConnected() then SendNoEcho("") end
return
end
local m = core.match("(?:City|Commune)\: ([A-Z][a-z]+)", w)
if not m then
ui.message("This person appears to either be a rogue, or not exist at all.")
if IsConnected() then SendNoEcho("") end
return
end
add_name(player, m[1])
if IsConnected() then SendNoEcho("") end
end
The thing about this though, is that it hangs while getting the information. I discussed this with a friend, and he mentioned that this may be exacerbated if the host was experiencing problems. He mentioned that to remove the hang, I would have to use a non-blocking method and utilize coroutines. I've tried a few things, but they did not seem to work at all. I've done searches and fail to really understand the code presented.
How would I take advantage of coroutines to speed this up?
I would show my previous attempts at using connect and receive, but I scrapped them out of frustration. | Top |
|
Posted by
| Rivius
(99 posts) Bio
|
Date
| Reply #1 on Fri 16 Sep 2011 12:55 AM (UTC) |
Message
|
function whois(player, html)
local w = html
if not w then
ui.alert("There has been an error retrieving information from the website.")
if IsConnected() then SendNoEcho("") end
return
end
local m = core.match("(?:City|Commune)\: ([A-Z][a-z]+)", w)
if not m then
ui.message("This person appears to either be a rogue, or not exist at all.")
if IsConnected() then SendNoEcho("") end
return
end
add_name(player, m[1])
if IsConnected() then SendNoEcho("") end
end
function download_page(player)
local h = "www.ironrealms.com"
local c = assert(socket.connect(h, 80))
c:send("GET http://www.ironrealms.com/game/honors/Lusternia/"..player.." HTTP/1.0\r\n\r\n")
local x = coroutine.create(
function ()
whois(player, receive(c))
end)
coroutine.resume(x)
end
function receive(c)
local status = "timeout"
local msg, a
c:settimeout(0)
while (status == "timeout") or (status==nil and a~=nil) do
a, status, d = c:receive()
if a then msg = msg..a end
if d then msg = msg..d end
if status == "timeout" then
coroutine.yield(true)
end
end
c:close()
return msg
end
Here's my lastest attempt to get it to work, but it just does nothing when I run the download function. | Top |
|
Posted by
| Nick Gammon
Australia (23,140 posts) Bio
Forum Administrator |
Date
| Reply #2 on Fri 16 Sep 2011 01:59 AM (UTC) |
Message
| Luasocket itself supports non-blocking calls, because I wrote a small MUD server using it. However I'm not sure that the HTTP interface makes use of that.
I don't think coroutines will directly help, because the underlying call still blocks.
I'm not sure this helps:
That effectively means "no timeout" doesn't it? (that is, blocking)
Basically for non-blocking to work you need a different design. That is, initially you send the request to the web server. That can (hopefully) immediately exit (although DNS lookups might slow it down quite a bit).
Then you need to periodically check (eg. every second) to see if the data has arrived. There is no way to have a non-blocking, but atomic, function call that will get something like whois info.
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Larkin
(278 posts) Bio
|
Date
| Reply #3 on Fri 16 Sep 2011 02:28 AM (UTC) |
Message
| I swear I've seen the settimeout(0) work in the past, allowing the while loop to go at full speed, yielding as needed. Now, it requires a value of at least 1 for the timeout, and the function still seems to run in the foreground. Obviously, we don't really get the proper use of coroutines to do asynchronous things, like reading from a socket... | Top |
|
Posted by
| Oligo
(26 posts) Bio
|
Date
| Reply #4 on Thu 24 May 2012 08:26 PM (UTC) Amended on Thu 24 May 2012 11:16 PM (UTC) by Oligo
|
Message
| Rivius can you paste your code for your IsConnected() function. I'd be interested to see it to see if I could leverage it for a little luasocket script I'm working on.
The
helped a lot, thnx!
Hm, based upon your suggestion, do you think creating a timer with a 1 second interval within MUSH and periodically reading the socket via c:receive() with a c:settimeout(0) is the best way to go then? It seems that's the strategy if you want MUSH to be responsive and still be able to check for messages from any TCP server you're connected to.
|
mud.arctic.org : 2700 | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
21,791 views.
It is now over 60 days since the last post. This thread is closed.
Refresh page
top