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

rednet.receive is not returning at all.

Started by Treyzania, 16 February 2015 - 05:12 PM
Treyzania #1
Posted 16 February 2015 - 06:12 PM
So I have this function (put inside a coroutine) that isn't working. For some reason, the call to
rednet.receive
never returns a value, even long after the 5 seconds that it's given in the parameter.


local function recvLoop()
  
	print("RedMesh coroutine started!")
	vprint("Checking on protocol \"" .. rnProtocolName .. "\".")
  
	while true do
	  
		print("Beginning loop run...")
	  
		local sender, msg, proto = rednet.receive(rnProtocolName, 5) -- THIS NEVER RETURNS
	  
		vprint("I got something...")
	  
		local env = {}
	  
		if pcall(function() env = textutils.deserialize(msg) end) then -- Tries to deserialize.
		  
			vprint("Packet received!  Handling...")
		  
			local mType = env["type"]
			local sender = env["sender"]
			local data = env["contents"]
		  
			local senderId = data["sender_id"]
			local mProto = base64.from_base64(data["protocol"])
			local msg = base64.from_base64(data["message"])
			local sig = data["signature"]
		  
			if savePackets then savePacket(env) end
		  
			if processable(sig) then
			  
				if mType == "p2p" then
				  
					local dest = data["dest"]
				  
					vprint("P2P packet...")
				  
					if dest == ident then
						vprint("...got it!")
						pushDownwards(data)
					else
						vprint("...repropegating!")
						repropegate("p2p", data) -- Pass it along if it isn't ours.
					end
			  
				end
		  
				if mType == "broadcast" then
				  
					vprint("Broadcast packet!")
				  
					pushDownwards(data)
					repropegate("broadcast", data)
				  
				end
			  
			end
		  
		else
			vprint("Error in de-serialization, sender is " .. tostring(sender) .. ".")
		end
	  
	end
  
end

I know this because in the output of the program, "Beginning loop run…" is shown, but "I got something…" never appears, ever, even when I send a barrage of both P2P and broadcast messages over both wired and wireless modems. Yes, I am sure that I opened the modem, as the red ring at the base of the modem(s) turns on.
MKlegoman357 #2
Posted 16 February 2015 - 09:59 PM
It's probably because if your coroutine manager. Basically, whenever you resume a coroutine you have to pass it an event. This is how CC event system works. Whenever you pull an event you are actually doing coroutine.yield( event ). When an event happens the coroutine should be resumed with all the event's parameters. Take a look at the parallel API or multishell and how they manage coroutines.
Treyzania #3
Posted 16 February 2015 - 10:39 PM
Basically, whenever you resume a coroutine you have to pass it an event.Take a look at the parallel API or multishell and how they manage coroutines.

But what I'm trying to do is make an API with an init function which sets up this coroutine (and a few other things), then returns and passes control back to the user's program. This makes parallel inapplicable.

Here's the two lines from the init function that are relevant:


recv = coroutine.create(recvLoop)
coroutine.resume(recv)

Thanks.
Bomb Bloke #4
Posted 16 February 2015 - 10:53 PM
You must resume the coroutine every time it yields. The function does so whenever it tries to pull an event - eg, when it calls rednet.receive().

MKlegoman isn't suggesting that you use the parallel API, but rather that you read its source in order to learn how to manage coroutines yourself.