im making a...*GASP* game, and I need to send advanced info through the network. For example I would like to send an object of the type "Player" so that the client only needs to draw it and that's that. This would mean sending a position-vector, velocity vector, current frame of animation and/or other things.

How would I go around doing this in a way so I wont have to write tons of code to convert between serverside and clientside information?

I have some kind of idea that the Serializable interface might come in handy, meaning I would have to implement it and find a way to serialize the information I need for my server/client communication.

Another problem I have is: How do you avoid having a duplicate class for the server and client when sharing objects of the same type? One solution would be to only send primitives or standard java classes, then convert them at clientside...this will result in lots of coding work with boring conversion stuff...

Please consider these TWO questions In advance I ask of you to read the entire post before replying.

<i8b4uUnderground> d-_-b<BonyNoMore> how u make that inverted b?<BonyNoMore> wait<BonyNoMore> never mind

To start with, just have one class, and use it for both client and server. Secondly, simply implement the Serializable interface - it's got no methods - and ensure all your member variables are themselves also Serializable, or marked transient. And it'll just magically work.

Later on you can get clever with Externalizable and so on to optimise performance.

To start with, just have one class, and use it for both client and server...

Can you elaborate on this part? I don't understand what you mean by this. And thanks for your insight on Serializable, im a lazy coder so that sounds very neat not having to do any extra implementing hehe . (it's better to be lazy than sloppy!)

<i8b4uUnderground> d-_-b<BonyNoMore> how u make that inverted b?<BonyNoMore> wait<BonyNoMore> never mind

Create a jar containing the classes you want to use on the server and the client and include that one in the classpath of both.

Said in another way: create 3 projects in your IDE. A library jar, say "mygame-common" a server project "mygame-server" and the game itself ("mygame" ). Then you declare "mygame-common" in the dependencies of your other two projects.

This way, you can use the same classes for both, your server and your client, and when you create your deployment distribution, the IDE copies the generated "mygame-common.jar" to the distribution directories of both projects.

So in practise, I would just compile the "common" project and then dont do anything else. Then for the other projects I would just add the jar from the standard build-folder of the common project? This way I wouldnt have to do anything else than building the common classes and the running my other projects for them to see the new classes of the common package..?

<i8b4uUnderground> d-_-b<BonyNoMore> how u make that inverted b?<BonyNoMore> wait<BonyNoMore> never mind

Achtually you shouldn't call flush() after every object sent. Just after you are finished with a state update. Also dont close and reopen connections after sending an object. Keep the connection open and just reconnect, if it is lost or the game quits.

Sending Serialized objects with the standard ObjectOutputStream is really inefficient since it sends across the complete package name and a lot of extraneous information. If you care about real-time performance at all I would recommend against it. I ended up writing my own solution in JGN using Reflection that ended up being light-years faster than Java's built-in functionality because it first negotiates all the classes that will be communicated and assigns short values to them so from then on it doesn't have to send anything but a short referencing what the class is and the actual field data of the object.

Sending Serialized objects with the standard ObjectOutputStream is really inefficient since it sends across the complete package name and a lot of extraneous information. If you care about real-time performance at all I would recommend against it. I ended up writing my own solution in JGN using Reflection that ended up being light-years faster than Java's built-in functionality because it first negotiates all the classes that will be communicated and assigns short values to them so from then on it doesn't have to send anything but a short referencing what the class is and the actual field data of the object.

Would you feel like sharing your code for your own serializing method? I used Reflection for some database-persistance library, and I must say I don't feel like going through hell AGAIN.... I hope you will share it with us/me.

*edit*

just looked at the JGN package, it seems like its a shitload to swallow when all I need is a small system to serialize an object in a compact manner...

<i8b4uUnderground> d-_-b<BonyNoMore> how u make that inverted b?<BonyNoMore> wait<BonyNoMore> never mind

ok, this thread has been very rewarding for me. I will consider using the JGN and possibly the reworked code you posted. On the other hand, I see some benefits from implementing some specific network-communication, due to the added control of exactly what data is being sent. Sending a String-arrays or int-arrays and then in turn parsing them on the other side would give me total control and minimal overhead of what data is being sent. On the other hand, this is a heavy burden for the programmer, meaning implementing new functions could be a pain. However, I might be able to create some generalized state-objects and create a dedicated serialization scheme for this particular object. This would be reusable for both particles, actors and what not.

Does anyone have experience with the "coding specific serialization" plan? I think this is what I will try since I have tried it for a simple application, and the performance was perfect. It supported at least 50 updates on 10 clients each second.

<i8b4uUnderground> d-_-b<BonyNoMore> how u make that inverted b?<BonyNoMore> wait<BonyNoMore> never mind

Actually that is what I mean by specific serialization, just implementing each case of the transmission. Just like your example, but that could be hard work for the programmer in the long run. It IS fast though, so I guess ill go with that idea

<i8b4uUnderground> d-_-b<BonyNoMore> how u make that inverted b?<BonyNoMore> wait<BonyNoMore> never mind

Actually that is what I mean by specific serialization, just implementing each case of the transmission. Just like your example, but that could be hard work for the programmer in the long run. It IS fast though, so I guess ill go with that idea

XD I'm not meaning its difficult, but look at how many lines you have. Plus you need an equal amount of function calls at the client-side. I'd rather serialize the data, send it once and then unserialize it at clientside for example. I will post some code once I have thought through my idea.

<i8b4uUnderground> d-_-b<BonyNoMore> how u make that inverted b?<BonyNoMore> wait<BonyNoMore> never mind

That's sort of the idea of JGN except without putting the burden on the developer JGN does it all auto-magically for you.

The preferred way is to create beans that extend the Message class and simply contains getters / setters for data that you want to transfer across and it handles all the serialization/deserialization for you. The idea is to remove clutter and specific networking crap from game development to let the developers focus on the rest of the game instead of wasting time writing networking code. On the other end you simply add MessageListeners to listen for specific messages and that's it.

XD I'm not meaning its difficult, but look at how many lines you have. Plus you need an equal amount of function calls at the client-side. I'd rather serialize the data, send it once and then unserialize it at clientside for example. I will post some code once I have thought through my idea.

Do what you like, just keep in mind that ObjectInput/OutputStream are much slower than using byte streams due to unessecary data being sent.

Renoria, I totally agree that it's sending a lot of excess information, but what you suggested is a lot of manual conversion for the developer where Reflection can take all the pain away for you.

Yeah, but sending all that other crap (package names, method names) etc is a big waste of bandwidth, while using a simple byte stream writer doesn't use nearly as much, and you can actually control what is being sent/recieved. I would probably wrap the InputStream into a java.io.DataInput/OutputStream to use methods such as writeInt, writeByte, writeShort, readInt, readShort etc.

You could also use Apache MINA, xSocket or Riven's NIO Wrapper, or any other NIO/IO Lib.

Ok, guys I have a serious problem now. I really can't seem to solve this mystery.

Whenever I send strings, string-arrays or the like via ObjectOutputStream.writeObject() it goes super smooth(0-1 ms delay on localhost), but then whenever I send byte[]'s with the write() command, I get a delay of 80 ms. It is only delayed when the server sends back another byte[] to the client. I have 1 server and one client right now, and I have spent hours without finding the problem...

in the above code, I have commented out the sendBytes command, and the delay is 1 ms for sending and receiving the array. When I uncomment it so it is called I get 80 ms of delay. Can someone tell me what could be wrong? It shouldnt take longer for my server to send the bytes than for my client right?

What makes this weird is the fact that it works for String[] arrays which in my world should be MUUUCH bigger than byte-arrays... The data in the byte[] arrays is just 4 doubles an 2 ints.

Here is some more code specific to this problem(I'm sorry its really nasty cuz im debugging it right now):

Perhaps the problem is the way you read the bytes... you're asking the inputstream for up to 800 bytes, maybe it's sitting there waiting for a tiny bit to see if there are any more to come. See if using read(byte[], int, int) fixes it by specifying exactly how many bytes you're expecting.

Perhaps the problem is the way you read the bytes... you're asking the inputstream for up to 800 bytes, maybe it's sitting there waiting for a tiny bit to see if there are any more to come. See if using read(byte[], int, int) fixes it by specifying exactly how many bytes you're expecting.

Cas

pretty sure this isnt the problem. I used to do it using "redObject" and "writeObject" casting them for whatever I was sending. This gave me the exact same delay(80 ms). And I dont think i'm asking for anything by handing in the 800 size aray, because it just edits the first 0-n spots in the array(one would think), so as long as the array is big enough, i'm safe.

<i8b4uUnderground> d-_-b<BonyNoMore> how u make that inverted b?<BonyNoMore> wait<BonyNoMore> never mind

Yeah, but sending all that other crap (package names, method names) etc is a big waste of bandwidth, while using a simple byte stream writer doesn't use nearly as much, and you can actually control what is being sent/recieved. I would probably wrap the InputStream into a java.io.DataInput/OutputStream to use methods such as writeInt, writeByte, writeShort, readInt, readShort etc.

You could also use Apache MINA, xSocket or Riven's NIO Wrapper, or any other NIO/IO Lib.

My point was in reference back to Reflection, not using Java's built-in Java Object Serialization crap. JGN uses custom reflection code so you don't deal with any of the extra garbage that get sent across and it's really a very simple concept.

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