This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
lukasni's profile picture

[Lua][Question] Concurrent rednet messages

Started by lukasni, 04 January 2013 - 12:20 PM
lukasni #1
Posted 04 January 2013 - 01:20 PM
EDIT: SOrry about the title, forgot to actually put one in there, it's late, fixed now…

Hello everyone,

First post here on the cc forums. I'm currently working on a small server/client protocol using rednet for keeping track of my turtles. Now i've run into a bit of a snag concerning message "collision". This is mainly a problem when launching the game, but might randomly occur at any point in time.

Here is a simplified version of the client announce function. The problem i'm having is, that some turtles never get recognized by the server on statup since the rednet events seem to get lost on the server. Now, is it possible to somehow "queue" events, so that the important one (the acknowledgement from the server) doesn't get drowned in the different broadcasts the clients are sending?


local breakCond = false
while not breakCond do
  event, p1, p2 = os.pullEvent()

  if event == "rednet_message" then
	sender  = p1
	package = textutils.unserialize(p2)
	if package.dest ~= nil then
	  if (package.type == tnt.ACKNOWLEDGE) and (package.dest == os.getComputerID()) then
		print("Acknowledged by Server ID"..sender)
		breakCond = true
	  end
	end
  elseif event == "timer" then
	print("Request timed out")
	breakCond = true
  end
end

Thanks a bunch in advance,
-Lukas
ChunLing #2
Posted 04 January 2013 - 01:55 PM
Events are queued already, and if you just keep running the loop rather than setting breakCond to true the first time you get a valid message, you can pull and respond to those other events.
lukasni #3
Posted 04 January 2013 - 02:44 PM
Thing is, the loop is supposed to break on the first valid message, completing the handshake with the server. It never seems to get the message though. But if the events are already queued, the problem has to be on the server side. I'll investigate there and keep you updated, thanks =)
ChunLing #4
Posted 04 January 2013 - 03:07 PM
Right after "if event == "rednet_message" then" add a debug print, like: print(p1,": ",p2)

That should help you figure out why you're messages aren't fitting the criteria.
lukasni #5
Posted 04 January 2013 - 03:36 PM
Tried that, but, as it turns out, on the wrong machine. The problem is definitely occurring server-side, but I haven't been able to track it down.

This is the code from the server side. I removed a lot of code to dumb it down to the basic handshake functionality, the problem is still occurring at this point.


while true do
  event, p1, p2 = os.pullEvent()

  if event == "rednet_message" then
	sender = p1
	package = textutils.unserialize(p2)
  
	if package.dest ~= nil then
	  if (package.type == tnt.ANNOUNCE) and (package.dest == os.getComputerID() or package.dest == 0) then
		rednet.send(sender,tnt.acknowledge(sender))
		print("Client announced: ID"..sender)
	  end
	end
  end
end

As for my testing setup: I have three turtles running the announce code from my initial post (the actual announce is a broadcast sent right before starting the 5s timer, if that's of any use)
A fourth computer is acting as the server. Now, upon loading the world, the turtle with the lowest id gets recognized by the server, the other two do not, their request times out. However, if I then reboot those turtles separately, the server recognizes the announce and registers the turtle as intended.

Since this all seems to point toward some kind of event collision I tried running the code with an initial sleep time based on the Computer ID, just a way to make them all sleep for different times. That worked just fine, everything got recognized by the server. The question is now, how do I avoid that collision without having to wait for a few seconds on load and without the constant fear that turtles might send a message at the same time by chance (I have many turtles, it might happen…)
ChunLing #6
Posted 04 January 2013 - 04:01 PM
Well…hmmm…given what I know about how CC works, it seems like this is only a problem you need to worry about at startup. See, because the LuaJ environment only runs one computer at a time, two turtles can't send a message at exactly the same time, it shouldn't even be theoretically possible.

Then again, it shouldn't be happening on startup either, so maybe someone else can weigh in?
lukasni #7
Posted 04 January 2013 - 04:12 PM
I just can't shake the feeling that I'm overlooking something stupidly simple in my code that is causing the messup. But if no solution can be found for the startup problem, I guess could keep a small "random" delay in there to avoid any collisions.

Anyways, thanks for all the help you've provided so far, it's definitely helped me in understanding the CC event system a little better, which was the initial motivator for wanting to develop my Turtle Network Talk Protocol (TNT in short ;)/> ) in the first place. And i'm sure this is just a small bump on the road to turtle-powered mastery over time and space. Mostly space.