peer2peer / private server

Oh, and one more question:

Care to explain synchronisation mechanism?

In particular, is there any way to ensure everyone is still properly synchronised to everyone else after gaming for a while?

Completely manual. Each player who joins the network must manually synchronize with another player who is already synchonized with the main group.

I’m not quite sure what you mean by this. Once synchonized, players should no become out of sync unless they are disconnected and reconnect, in which case they should immediately re-synchronize.

Could please list the source files you ended up changing.

Thx,

src/Vassal/chat/CgiServer.Status.java
src/Vassal/chat/DynamicClient.java
src/Vassal/chat/HttpMessageServer.java
src/Vassal/chat/MainRoomChecker.java
src/Vassal/chat/node/NodeClient.java
src/Vassal/chat/node/Server.java
src/Vassal/tools/version/VersionUtils.java

Uh, not what I had in mind, not the user side of the process. What’s the process behind the synchronizing, how does Vassal handle it?

Also, would it be possible for Vassal to automatically detect disconnects and inform about those? Over the years I played with a few people who suffered from disconnects for no apparent reason and it wasn’t usually immediately visible (their names still lingered in the room for a while, with no sign of losing connection on their side as well). So we had to go through the “we don’t see your rolls, did you roll?, oh not again” routine with them several times per game. It would be useful if Vassal could inform about disconnects more or less immediately, and an option to force reconnection and resynchronisation would be even more useful.

Thanks for that.

In a p2p network, there is no central server, no ‘master’ copy of the game. Vassal cannot automatically know who should sync with whom, so it is completely manual (which is how it used to work for the main server also prior to 3.1).

Synching is handled by the Synch Command, which basically sends a full dump of the commands required to reproduce the current game environment.

Well, it does. Vassal depends on Java reporting that there has been a disconnect and handles it appropriately. If there are some sort of disconnects that Java doesn’t see, then it is impossible for Vassal to be aware of them. I did fix several bugs where the processes that listen on the ports to peers where left running after a disconnect, this could have something to do with the problem. See if you have the same level of problems with the latest version.

Again, in a p2p network, it is not possible to tell which user should be synchronized with. Any sort of automatic synchronization in a p2p network will inevitably get it wrong sometimes, so it has to be done manually by the players.

Still no luck testing it with three players, and it’s already implemented in the 3.2.5 release. Oh well.

Looks pretty promising though. Seems like connections interface is not that bad now, and we didn’t seem to have any serious connection delays.

I suggest changing the “Connect” button label to something else in future releases, in order to avoid confusion with the standard connect button. Perhaps “Join P2P” or something.

An old encoding bug is still present. I describe it in another thread.

I’d like to gain better understanding of the flow of data between users with this. Not in terms of specific code stuff - in general terms, like what’s sent to whom when a player does something at the table, and in what order.

Not enough information, that tells me nothing as to what your problem is. Can you please post the exact sequence of events you are testing, what happens, what messages etc.

!!! So it is working? I am confused, is it working for you or not.

All clients are directly connected to all other clients. When one player does something, a vassal Command representing that action is sent to all other clients. That command is decoded and acted out on by each of the other clients, bringing them to the same state as the client who initiated the action.

To clarify your confusion: I only tested 3.2.5 p2p with one other person and it seems to work fine enough for two players, other than the encoding bug. I wanted to test it with three players, but there was no opportunity. Basically, until I see it working with three or more people, I remain skeptical regarding this being a fully viable alternative for the main server. I guess you know how problematic p2p mode was prior to 3.2.

So, I’m just expressing my regret for not being able to test your changes with three or more people and provide you with feedback before 3.2.5 was released. I hope you managed to give it enough testing with multiple players, or that other people provided you with enough test results.

So say you have players A, B and C. Player A connects to P2P network using player B’s IP, player C connects using player A’s IP. Then A starts a game, B and C synchronize to A.

Do I understand it correctly that this automatically synchronizes B and C together as well? From then on, each move of C is sent to A and B, even though C as a player doesn’t even know B’s IP and doesn’t have him listed in the contacts list?

Or is it that when C does something A’s state is updated, and only then B’s state updates to match A’s state? Like, A works as an intermediary, and B’s and C’s states never update directly?

Also, was B’s connection info automatically sent to C at the moment of C’s connection to A? Is it stored somewhere, or will it be lost the moment they disconnect from the P2P network (unless they manually add each other to the contacts list)?

Ok

Yes, that is correct.

No, C sends the Command directly to both A and B

Yes

Yes it is stored somewhere (inside your Vassal client) and Yes, it is lost when they disconnect from the P2P network.

Thanks for explaining all that. It should make it easier for me to understand related bugs and issues.

The problem is, I’ve just tested P2P with three machines, using the LAN trick you taught me in the other thread.

Aaand… it doesn’t work as described. It seems things break with more than two participants.

  1. I’ve set up a test P2P network, with password, on my primary computer, and opened one of my saved games.
  2. I connected from my laptop, using the password and primary’s IP.
  3. I connected from my secondary computer, using the password and laptop’s IP. Note that I specifically did not add primary to contacts here for test purposes.
  4. At this point, on laptop, I could see both primary and secondary in the main room. I could only see laptop from both primary and secondary. Apparently primary’s connection info was not sent automatically to secondary, even though it should according to your above explanation.
  5. I synchronized from laptop to primary. Laptop reported it was sending game info to secondary, but when I checked secondary nothing changed there.
  6. I synchronized from secondary to laptop. The game appeared, as it should.
  7. I returned to primary and moved a token. Laptop’s game state was updated. Secondary’s was not.
  8. I rolled a die on laptop. Both primary’s and secondary’s game states were properly updated.
  9. I did some stuff on secondary. Laptop’s game state was updated. Primary’s was not.

It appears laptop worked as an intermediary after all. So, it’s not enough to connect to any player in the network.

Based on my experience with the old P2P, I believe it could work if I add primary to contacts on secondary, and secondary to contacts on primary. But I’m tired with all that testing and running up and down the stairs for today, so perhaps another day.

Even if it works properly, it means setting up a P2P network will become increasingly complicated with each additional player, if everyone needs to know everyone else’s IP, and especially so for people with dynamic IPs (like half my group).

Unless I was supposed to use one machine as a hub, and synchonize both others to it, rather than trying to create a chain? Based on your explanations it seemed to me that a chain should work.

BTW, I’ve just noticed that contact list still doesn’t save properly and disappears after restarting Vassal (under Ubuntu, at least, I didn’t check on Windows). Likewise, custom P2P networks (with non-default name and password) added through the server tab in preferences don’t save properly and disappear after restarting Vassal (the default network is set as current connection mode after the restart).

Well, that’s where things are going wrong. You are getting different results from what I expect, or what I see when I test. The Primary and Secondary should appear in each others user list at that point. It is possibally a firewall issue on one of the machines?
Anything unusual in the three error logs?

Can you please try this on a single Linux machine:

  1. Start Client 1, change user name to A, set P2p Listen port to 5051
  2. Start Client 2, Change User name to B, set p2p listen port to 5052
  3. Start Client 3, Change User name to C, set p2p listen port to 5053
  4. Start P2p server on all three clients
  5. Connect to 127.0.0.1:5051 from client 2 (B)
  6. Connect to 127.0.0.1:5051 from client 3 (C)
  7. All three clients should now show all three users A, B and C in the user list.

Thanks. I have reproduced this. Exiting the Module manager is overwriting the server preferences. I have opened bug

Bug 10179 - Module manager is overwriting P2P server preferences

for this.

I don’t think so, but how do I make sure?

Each machine runs a different version of Linux, if that matters. Specifically, I have a fresh installation of Lubuntu on laptop, Ubuntu 12.10 on primary, and some earlier version of Ubuntu on secondary.

However, none of those have any non-default firewall software installed and all connect through the same router, which has a single and properly working firewall rule for Vassal. Last summer I managed to get a more or less working three-way P2P connection with other people, using Vassal 3.1, and nothing changed in my router configuration since then.

Should I try a different port number for each machine, like in your last post?

Well, there were no error messages, so it didn’t occur to me to check error logs. Unfortunately, I’m not sure if any logs survived my cleanup after the test. I’ll try to remember to check logs next time (I expect to find some time for another three machine test next week).

I tried that on my primary machine. Works as expected. It also works properly when I try to connect in chain. Actually, it still works even if I leave the default port number everywhere.

All clients see all other clients, all synchronize properly, regardless of connection/synchronization order.

So it seems something is different when different machines connect.

Also, despite this working, error log shows some errors:

"2013-05-20 14:17:55,200 [1-AWT-EventQueue-0] WARN VASSAL.launch.BasicModule - Bucket of Dice version 2.0
2013-05-20 14:17:55,206 [1-AWT-EventQueue-0] INFO VASSAL.build.module.ExtensionsLoader - Loading extension /home/filip/Desktop/Vassal/bucket-2.0_ext/wfrp
2013-05-20 14:17:55,369 [1-AWT-EventQueue-0] WARN VASSAL.tools.logging.LoggedOutputStream - – Extension wfrp v1.3 loaded
2013-05-20 14:18:12,225 [1-AWT-EventQueue-0] ERROR VASSAL.chat.ChatServerFactory - "

This one repeats three times, only the other two instances are tagged as 4-AWT and 7-AWT respectively.

There’s also this one ending the log:

“2013-05-20 14:21:34,593 [0-IPC receiver for 1646732214] ERROR VASSAL.tools.ipc.IPCMessageReceiver -
java.io.EOFException: null
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source) ~[na:1.7.0_17]
at java.io.ObjectInputStream.readObject0(Unknown Source) ~[na:1.7.0_17]
at java.io.ObjectInputStream.readObject(Unknown Source) ~[na:1.7.0_17]
at VASSAL.tools.ipc.IPCMessageReceiver.run(IPCMessageReceiver.java:34) ~[Vengine.jar:na]
at java.lang.Thread.run(Unknown Source) [na:1.7.0_17]
2013-05-20 14:21:37,964 [4-AWT-EventQueue-0] INFO VASSAL.build.GameModule - Exiting
2013-05-20 14:21:38,331 [0-IPC receiver for 334807511] ERROR VASSAL.tools.ipc.IPCMessageReceiver -
java.io.EOFException: null
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source) ~[na:1.7.0_17]
at java.io.ObjectInputStream.readObject0(Unknown Source) ~[na:1.7.0_17]
at java.io.ObjectInputStream.readObject(Unknown Source) ~[na:1.7.0_17]
at VASSAL.tools.ipc.IPCMessageReceiver.run(IPCMessageReceiver.java:34) ~[Vengine.jar:na]
at java.lang.Thread.run(Unknown Source) [na:1.7.0_17]
2013-05-20 14:21:41,836 [1-AWT-EventQueue-0] INFO VASSAL.build.GameModule - Exiting
2013-05-20 14:21:42,198 [0-IPC receiver for 1072749565] ERROR VASSAL.tools.ipc.IPCMessageReceiver -
java.io.EOFException: null
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source) ~[na:1.7.0_17]
at java.io.ObjectInputStream.readObject0(Unknown Source) ~[na:1.7.0_17]
at java.io.ObjectInputStream.readObject(Unknown Source) ~[na:1.7.0_17]
at VASSAL.tools.ipc.IPCMessageReceiver.run(IPCMessageReceiver.java:34) ~[Vengine.jar:na]
at java.lang.Thread.run(Unknown Source) [na:1.7.0_17]
2013-05-20 14:21:44,187 [0-AWT-EventQueue-0] INFO VASSAL.launch.ModuleManagerWindow - Exiting”

But I guess those are all harmless and unrelated to the problem?

Thus spake Filip:

There’s also this one ending the log:

“2013-05-20 14:21:34,593 [0-IPC receiver for 1646732214] ERROR
VASSAL.tools.ipc.IPCMessageReceiver -
java.io.EOFException: null
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown
Source) ~[na:1.7.0_17]
at java.io.ObjectInputStream.readObject0(Unknown Source) ~[na:1.7.0_17]
at java.io.ObjectInputStream.readObject(Unknown Source) ~[na:1.7.0_17]
at VASSAL.tools.ipc.IPCMessageReceiver.run(IPCMessageReceiver.java:34)
~[Vengine.jar:na]
at java.lang.Thread.run(Unknown Source) [na:1.7.0_17]
2013-05-20 14:21:37,964 [4-AWT-EventQueue-0] INFO
VASSAL.build.GameModule - Exiting
2013-05-20 14:21:38,331 [0-IPC receiver for 334807511] ERROR
VASSAL.tools.ipc.IPCMessageReceiver -
java.io.EOFException: null
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown
Source) ~[na:1.7.0_17]
at java.io.ObjectInputStream.readObject0(Unknown Source) ~[na:1.7.0_17]
at java.io.ObjectInputStream.readObject(Unknown Source) ~[na:1.7.0_17]
at VASSAL.tools.ipc.IPCMessageReceiver.run(IPCMessageReceiver.java:34)
~[Vengine.jar:na]
at java.lang.Thread.run(Unknown Source) [na:1.7.0_17]
2013-05-20 14:21:41,836 [1-AWT-EventQueue-0] INFO
VASSAL.build.GameModule - Exiting
2013-05-20 14:21:42,198 [0-IPC receiver for 1072749565] ERROR
VASSAL.tools.ipc.IPCMessageReceiver -
java.io.EOFException: null
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown
Source) ~[na:1.7.0_17]
at java.io.ObjectInputStream.readObject0(Unknown Source) ~[na:1.7.0_17]
at java.io.ObjectInputStream.readObject(Unknown Source) ~[na:1.7.0_17]
at VASSAL.tools.ipc.IPCMessageReceiver.run(IPCMessageReceiver.java:34)
~[Vengine.jar:na]
at java.lang.Thread.run(Unknown Source) [na:1.7.0_17]
2013-05-20 14:21:44,187 [0-AWT-EventQueue-0] INFO
VASSAL.launch.ModuleManagerWindow - Exiting”

But I guess those are all harmless and unrelated to the problem?

This is normal for Java. There’s no way to cleanly close a socket
without generating an EOFException. Blech.


J.

Hi Filip,

The three machines you are testing with, They are all on the same LAN behind your router?

Thanks,
Brent.

Time to stop thinking about ‘chains’. There is no such thing in a p2p network. Once one machine connects to the network, all machines are (should be :slight_smile:) connected to each other directly.

I have set up three different Windows machines on my LAN and connected in various orders and in all cases, it has worked as expected. Sometimes it takes several seconds before both of the other machines to appear after connecting to one of them.

I don’t have the resources to set up 3 Linux machines, but I will try and install Ubuntu on one of my machines and do more testing.

Could you please try connecting between your three machines in different orders and see if that makes any difference.

Using different port numbers shouldn’t make a difference when using different physical machines, you only really need to change the port number if you are using multiple clients on the one machine.

Brent.

The three machines I used for Friday’s test are all on the same LAN behind the same router.

The one I used for single machine test is one of those machines.

Unless, of course, things don’t work as expected.

That’s my plan, but I won’t have enough time for that until next week. When I get down to it I will also test your fix for the encoding bug.

Oh, by the way, what happens (or rather: what should happen) when multiple players in a p2p network do things more or less simultaneously? Wouldn’t that cause some issues, especially if there’s a connection delay, like “overwriting” some moves when game’s state updates?

I tested three machine P2P connection with Vassal 3.2.6 today.

At first, I tried to connect in chain (A → B, B → C), like the last time. Didn’t work. Just as previously, the middle machine could see both others, but the first and the last machine in chain couldn’t see each other.

I noticed something interesting: the last machine to connect was receiving multiple “peer name (IP:port) connected” messages for a few moments after connecting. I didn’t manage to replicate this consistently, but it did occur several times during my later attempts.

Another minor issue here is that “peer name (IP:port) connected” messages still show 127.0.1.1 rather than the proper IP (clicking the P2P Network button now shows the proper local IP).

Then, I tried connecting in various other combinations and some worked. Many combinations did not work, even though according to your earlier explanations (if I understand them correctly), they should. Sometimes I could see every machine in the room from first and second machine, but not from the third one. Either way, after struggling for a while I found what appears to be a sure way to get a working p2p network.

It didn’t work when trying to connect both B and C to A, even though that worked in a single machine test with three clients.

It didn’t work after adding every IP on each machine. Then I managed to get a working three way connection somehow, disconnected and tried to replicate it, unsuccessfuly at first.

Then I noticed it’s actually possible to highlight several IPs on the list and connect to two (so presumably more) at the same time.

This made it work. On each machine, all others appeared in the room. So it seems the trick is to connect to both other machines from a single “network starter”. It’s not an ideal solution (somebody needs to collect IPs from all other players to start the network, rather than just send everyone a single number to connect to). However, at least it seems to be a working solution.

In summary:

A → B, B → C => BAD
B → A, C → A => BAD
A → B, A → C => GOOD

Also, 3.2.6 still doesn’t seem to save contact lists and custom P2P networks properly. After restarting Vassal I only see the default network and a blank contact list, both under Ubuntu and Windows.

I cannot reproduce the problems you are having creating a 3 way p2p network under Windows, it works perfectly.

I think this is actually a symptom of a deeper problem with the way vassal is finding IP numbers under Linux that is causing your troubles. I don’t have the resources to investigate this problem but will review the code. The fact that we have Vassal reporting the correct IP under Linux is a good start.

This bug is not simple to fix, have not attempted to yet. Still discussing potential solutions with Joel.