Tutorial: Online Multiplayer with PodSixNet

Post your own tutorials, guides and demos.

Post » Thu Jun 16, 2011 10:05 am

Here is my post to thank Scidave for the tutorial of this awesome subject. Have not tried the tutorial yet. Hoping it is "foolproof". :)
B
16
S
5
G
7
Posts: 599
Reputation: 5,000

Post » Thu Jun 16, 2011 10:07 am

Here is my post to thank Scidave for the tutorial of this awesome subject. Have not tried the tutorial yet. Hoping it is "foolproof". :)
B
16
S
5
G
7
Posts: 599
Reputation: 5,000

Post » Thu Jun 16, 2011 11:57 am

[quote="rogerty":dsbw4qup]Here is my post to thank Scidave for the tutorial of this awesome subject. Have not tried the tutorial yet. Hoping it is "foolproof". :)[/quote:dsbw4qup]
[quote="rogerty":dsbw4qup]Here is my post to thank Scidave for the tutorial of this awesome subject. Have not tried the tutorial yet. Hoping it is "foolproof". :)[/quote:dsbw4qup]
If it's worth saying, it's worth saying twice! :wink: :lol:

Krush.
B
2
S
2
G
3
Posts: 406
Reputation: 2,062

Post » Sun Jun 19, 2011 4:21 am

So I've been messing with this and have been able to get it working and to pass the data I want back and forth :) Thanks for the awesome tutorial.

One thing I don't get is, how can I limit the number of connections? I don't actually know how this works, just how to manipulate it to change it to pass the data I want around, so I'm not sure how to turn off the listening for new connections without disconnecting everything.

Right now the way it works is that the client and server are teh same cap, and a player chooses to either Host or Join (it's p2p). When one player joins, I want to stop listening for other players.

Edit: I seem to be having another issue as well. When the server and client change layouts (since its p2p both of them do this at the same time) sometimes the connection drops. I can't tell when or how to reliably reproduce it but it seems to happen often enough and not sure what causes it. Any ideas on whta I could try?
B
11
S
2
G
3
Posts: 283
Reputation: 1,968

Post » Sun Jun 19, 2011 8:36 pm

Hi!

[quote="Juryiel":10y9ykaa]When one player joins, I want to stop listening for other players.[/quote:10y9ykaa]

[code:10y9ykaa]
# function called on every connection
def Connected(self, player, addr):
statusText.AppendText("New Player" + str(player.addr) + "\n")
[/code:10y9ykaa]

In the above function in the Server code you want a line like this:

if len(self.players) == 2:
"Send a message to new client that game is full" and don't add the client to list.
else
add player to list and send him his number...

For the connection problem:

You could try this:

For the client:

[code:10y9ykaa]
try:
myclient.Pump()
except:
pass

[/code:10y9ykaa]

For the server:

[code:10y9ykaa]
try:
myserver.Pump()
except:
pass
[/code:10y9ykaa]


What may happen is packets are still being sent from client to server or server to client, but there isn't anybody there yet to handle it so you get an exception?? If so, then the above should solve it. If not, I'd need more details.


Glad the tutorial is helpful!
B
8
S
3
G
7
Posts: 835
Reputation: 5,313

Post » Sun Jun 19, 2011 8:58 pm

I did try a bunch of

try:

except:

combinations with server and client. The issue is the myserver.Pump() command in the new layout to which I'm switching for sure. If I put that in a try/except block, the popup error goes away, though I still cannot communicate between server and client any more.

The error message in particular is:

Traceback (most recent call last):
File "<string", line 1 in <module>
File "PodSixNet\Server.pyc", line 39, in Pump
File "asyncore.pyc", line 143, in poll
File "asyncore.pyc", line 80, in read
File "PodSixNet\Channel.pyc", line 52 in handle_error
File "asyncore.pyc", line 470, in handle_error
File "PodSixNet\Channel.pyc", line 59, in handle_close
File "<string", line 28, in Close
File "<string>", line 6769, in_getattr_
File "<string>", line 6782, in _getitem_

IndexError

The function Network_disconnected under the client also runs when this happens, so I guess somehow the connection is being lost or cut.

Also, is there no way to not even acknowledge incoming connections after I've gotten one player connected? I'm not sure it's ideal to have the server bother processing new incoming connections and sending error messages back. It'll work if that's the only way but I'd rather not even acknowledge any more connection attempts after a player has connected.
B
11
S
2
G
3
Posts: 283
Reputation: 1,968

Post » Sun Jun 19, 2011 9:11 pm

Here's some more information about how I'm switching layouts:

1. I check if both client and server are ready (via connection.Send({"action": readyToggle"}) and myserver.SendToAll({action": readyToggle"}) ) Client and Host can both change their ready status by checking a box, and each of the readyToggle functions update global vars corresponding to that.

2. The host checks if both ClientReady and HostReady are true (the globals mentioned above). If they are, it sets a global "starting" to 1.

3. When 'starting' is 1, the Host does:
myserver.SendToAll({"action": "ready"}), which just sets the Client's 'starting' to 1 as well
then it does myserver.Pump() and System.GoToLayout("Layout1")

4. At this point the Client's 'starting' is 1, which just calls a GoToLayout on the Client but without pumping any connections (so same as above except no myserver.Pump() or any other .Pump().

5. Both Client and Server are able to get to the new Layout, at which point I get the error message I mentioned.

6. In the new layout the first round of the game starts and both the host and the Client immediately call a readyToggle2 action which repeats every so often as it is checking to see if the Client and Host ready states (if they submitted their game orders, it's turn based game).

7. These actions are followed by myserver.Pump() (the one causing the problems I think) and connection.Pump and myclient.Pump(), with the myclient.Pump in a try/except block
B
11
S
2
G
3
Posts: 283
Reputation: 1,968

Post » Mon Jun 20, 2011 12:19 am

[quote="Juryiel":10fxzi74]Also, is there no way to not even acknowledge incoming connections after I've gotten one player connected? [/quote:10fxzi74]
Yes, you can just do:

def Connected(self, player, addr):
if len(self.players) < 2:
add the player...and do stuff

Once the player count reaches 2 the connection will be received but not processed. As far as not even receiving it goes, that would require some changes to the library.

>>> 7. These actions are followed by myserver.Pump() (the one causing the problems I think) >>> and connection.Pump and myclient.Pump(), with the myclient.Pump in a try/except block
Are you sure that the host acting as the server is not incorrectly acting as client too? I'm assuming you have that code in separate groups, etc (a server group and a client group).

Have you run wireshark to see what the packets look like right before the disconnect occurs?

When the server and client switch layouts there will be some desynchronization...the key is to get everybody synchronized again before starting processing events for the next layout.

You can also do some tests...make sure that the server has switched to Layout 2.. then wait 10 seconds and switch the client, etc... different stuff to be sure the server is ready to process packets in the second layout. Above that, I might have to see a .cap.
B
8
S
3
G
7
Posts: 835
Reputation: 5,313

Post » Mon Jun 20, 2011 3:17 am

Just in case this is useful to others, I was able to track down the problem with the help of scidave. Apparently trying to do connection.Send() over and over while the server is switching layouts causes the connection to close. The solution was to shut the client up while the server was changing layouts.
B
11
S
2
G
3
Posts: 283
Reputation: 1,968

Post » Fri Jun 24, 2011 8:25 am

Hmm, another question. I'm trying to do the following:

[code:alye2eyf]
For Each Units (Event)

myserver.SendToAll({"action": "updateUnits", "Home": SOL.Units.Value('Home'), "Type": SOL.Units.Value('Type'), "AttackTarget": SOL.Units.Value('AttackTarget'), "MoveTarget": SOL.Units.Value('MoveTarget'), "HP": SOL.Units.Value('HP'), "Team": SOL.Units.Value('Team'), "SpecialsTarget": SOL.Units.Value('SpecialsTarget')})

myserver.SendToAll({"action": "updateOrder", "Order": SOL.Units.Value('Order')})

Trigger Once while True (event)

myserver.SendToAll({"action": "processSync"})
[/code:alye2eyf]

If I comment out the two myserver.SendToAll() calls at the top (updateUnits and updateOrder) the third one works (processSync). However, if they are all uncommented, processSync does not seem to go through. It gets called, but the client on the other side does not receive it. Is there a limit to what I can send ? And how can I make sure that stuff gets there if I want to send a bunch of data?
B
11
S
2
G
3
Posts: 283
Reputation: 1,968

PreviousNext

Return to Your tutorials & example files

Who is online

Users browsing this forum: No registered users and 0 guests