Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (576)
games submitted by our members
Games in WIP (497)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Messaging Protocol using UDP  (Read 1016 times)
0 Members and 1 Guest are viewing this topic.
Offline ClickerMonkey

JGO Coder


Medals: 20


Game Engineer


« Posted 2013-01-23 17:21:44 »

I've had this messaging protocol designed and mostly implemented for sometime now, and I wanted to get others opinions on it. Specifically, what value do you see in this, or what things would you change.

It's a fairly simple, there are two things you need to understand:

  • Message = an object that can write and read to a ByteBuffer, has measurable size in bytes, and a unique id
  • Channel = you send messages along a channel. A channel has the following characteristics.
    • id = a number between 0 and the number of channels in your defined protocol)
    • reliable = whether or not the messages should reliably get to the other computer
    • ordered = whether or not the messages need to be ordered upon arrival
    • retryCount = the maximum number of times to try to resend a message if the channel is reliable
    • retryTimeLimit = the maximum amount of time in milliseconds to try to resend the message, if it hasn't been sent retryCount but the difference in time since the first send and now is greater than this then cease sending. notify client.
    • queuedTimeLimit = the maximum amount of time in milliseconds to keep a message in queue to write (messages are queued if you are trying to send too many and only so many can fit in the packet
    • priority = when there are too many messages for one packet, the channels with highest priority have their messages written out first

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
public interface Message {
    public void write(ByteBuffer out);
    public void read(ByteBuffer in);
    public int size();
    public int tag();
}
public enum Reliable { Yes, No; }
public enum Ordered { Yes, No; }
public class Channel {
    public final int id;
    public final Reliable reliable;
    public final Ordered ordered;
    public final int retryCount;
    public final int retryTimeLimit;
    public final int queuedTimeLimit;
    public final int priority;
}


I've also added this idea of a "PersistentMessage", essentially a message that you say most likely will be sent every packet (like user position). If the persistent message has data, it is prepared, then written out like a typical message.

1  
2  
3  
4  
public interface PersistentMessage {
    public boolean hasData();
    public void prepareData();
}


With all of this, both sides need to configure an agreed upon protocol:

1  
2  
3  
4  
5  
6  
7  
8  
9  
public class Protocol {
    public Protocol(int channelMax, int messageMax);
    public Protocol(Enum<?> channelEnum, Enum<?> messageEnum);
    public void setHeader(Message message);
    public void setChannel(int id, ... );
    public void setChannel(Enum<?> id, ...);
    public void addMessage(Message message);
    public void addPersistentMessage(PersistentMessage persistentMessage);
}


(something along those lines)

And of course the "connection"

1  
2  
3  
4  
5  
6  
7  
public class Connection {
    public Connection(Protocol protocol)
    public void send(int channel, Message message);
    public void send(Enum<?> channel, Message message);
    public void read();
    public void write();
}


(give or take some listeners that listen for dropped messages, when messages are read, etc)

Anyway, the whole point of this is to add flexibility... it all comes down to how much of your data is reliable, and needs to be ordered. If it always needs reliability, maybe TCP will work better. However even if you use TCP, there's one stream of reliable data... with this model there's any number of channels that can be marked reliable if a message is missed in one channel it won't hold up traffic in your channel.

A few examples of when I care about ordering/reliable

Sending User State = Reliable and Ordered (maybe not reliable depending on your server implementation)
Receiving Correct User State = Reliable and Not Ordered
Receiving Remote Entity State = Not Reliable and Ordered
Events (explosions, door opens, etc) = Reliable and Not Ordered
Text Messages = Reliable and Ordered

Are there any glaring flaws with this design that I've missed? At this point I think it's fairly flawless. I want to get this out there and usable sometime soon so other people can test it with their game types.

Offline theagentd
« Reply #1 - Posted 2013-01-23 17:42:20 »

1  
2  
public enum Reliable { Yes, No; }
public enum Ordered { Yes, No; }

You should change that to
1  
public enum Boolean {True, False;}

so it's reusable later.

Myomyomyo.
Offline ClickerMonkey

JGO Coder


Medals: 20


Game Engineer


« Reply #2 - Posted 2013-01-23 17:49:56 »

1  
2  
public enum Reliable { Yes, No; }
public enum Ordered { Yes, No; }

You should change that to
1  
public enum Boolean {True, False;}

so it's reusable later.

Haha, funny stuff. I've previously used boolean for these fields, but someone criticized me because true/false could mean anything, looking at someones code you can't tell without going to that method or seeing its documentation (which often is not easy, possible, or quickly done).

so if I call

1  
protocol.setChannel( ChannelEnum.TextMessages, Reliable.Yes, Ordered.Yes, Constants.RETRY_COUNT, ... );


It's easier to read than
1  
protocol.setChannel( ChannelEnum.TextMessages, true, true, Constants.RETRY_COUNT, ... );


However I use boolean everywhere when I could use enum... I don't know why I randomly choose to use one over the other.



Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline theagentd
« Reply #3 - Posted 2013-01-23 20:20:13 »

Hehe, glad you got the joke... =S

Well, it's just a minor detail anyway. If you think it looks better in your code (and I agree to some extent that it does) just go with it. Sorry for the semi-troll response, it was just a way too good opportunity to miss...

Myomyomyo.
Offline ClickerMonkey

JGO Coder


Medals: 20


Game Engineer


« Reply #4 - Posted 2013-01-23 20:24:37 »

Hehe, glad you got the joke... =S

Well, it's just a minor detail anyway. If you think it looks better in your code (and I agree to some extent that it does) just go with it. Sorry for the semi-troll response, it was just a way too good opportunity to miss...

I was expecting a comment from somebody, especially because it screams "THATS WHAT BOOLEANS ARE FOR!"

Offline sproingie
« Reply #5 - Posted 2013-01-24 02:50:29 »

You should change that to
1  
public enum Boolean {True, False;}


Don't you mean:
1  
public enum Boolean {True, False, FileNotFound;}

Offline ClickerMonkey

JGO Coder


Medals: 20


Game Engineer


« Reply #6 - Posted 2013-01-24 02:56:48 »

I've worked with so many people that use java.lang.Boolean opposed to boolean... it drives me up the wall. It's actually caused several problems. At work we also heavily pass around Integer and Object and cast to death... our system was initially developed by people who didn't know how to program... so we have hundreds of thousands lines of horrible code we maintain.

Offline Best Username Ever

Junior Member





« Reply #7 - Posted 2013-01-24 03:23:26 »

You should change that to
1  
public enum Boolean {True, False;}


Don't you mean:
1  
public enum Boolean {True, False, FileNotFound;}


It's
public enum Boolean {True, False, Two, Null;}


...

You could use boolean constants or bit flags.

1  
2  
3  
4  
5  
6  
protocol.setChannel( ChannelEnum.TextMessages, Reliable, Ordered, Constants.RETRY_COUNT, ... );
protocol.setChannel( ChannelEnum.TextMessages, Unreliable, Unordered, Constants.RETRY_COUNT, ... );

protocol.setChannel( ChannelEnum.TextMessages, Reliable, Constants.RETRY_COUNT, ... );
protocol.setChannel( ChannelEnum.TextMessages, Ordered, Constants.RETRY_COUNT, ... );
protocol.setChannel( ChannelEnum.TextMessages, Reliable | Ordered, Constants.RETRY_COUNT, ... );
Offline deepthought
« Reply #8 - Posted 2013-01-24 03:26:04 »

What do you do for data such as player positions that should be reliable, but will probably change before a resend? Do you send the old data or retrieve the new data?

jocks rule the highschools. GEEKS RULE THE WORLD MWAHAHAHA!!
captain failure test game
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (14 views)
2014-04-15 18:08:23

BurntPizza (12 views)
2014-04-15 03:46:01

UprightPath (25 views)
2014-04-14 17:39:50

UprightPath (11 views)
2014-04-14 17:35:47

Porlus (28 views)
2014-04-14 15:48:38

tom_mai78101 (50 views)
2014-04-10 04:04:31

BurntPizza (109 views)
2014-04-08 23:06:04

tom_mai78101 (209 views)
2014-04-05 13:34:39

trollwarrior1 (177 views)
2014-04-04 12:06:45

CJLetsGame (184 views)
2014-04-01 02:16:10
List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:05:20
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!