[Home] [Downloads] [Search] [Help/forum]


Register forum user name Search FAQ

Gammon Forum

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Lua
. . -> [Subject]  Luasocket and Coroutines?

Luasocket and Coroutines?

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page


Posted by Rivius   (99 posts)  [Biography] 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.
[Go to top] top

Posted by Rivius   (99 posts)  [Biography] 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.
[Go to top] top

Posted by Nick Gammon   Australia  (22,989 posts)  [Biography] 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:


c:settimeout(0)


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
[Go to top] top

Posted by Larkin   (278 posts)  [Biography] 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...
[Go to top] top

Posted by Oligo   (26 posts)  [Biography] 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


c:settimeout(0)


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
[Go to top] 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.


19,405 views.

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at HostDash]