Jnag's return (1.2.2)

Hello,

I would like to post a link to the Jnag library (Java Network API for Games), which is now open source, documented, and pretty mature. Please see the wiki for its documentation.

Any feedback, good or bad, is greetly welcome (please use the forum of Jnag for the feedback, thanks).

Vincent Cantin

I don’t feel like signing up on another forum, where I probably wouldn’t see replies anyway.

JAR != zip file. I always wonder why people put docs, etc in JARs. :slight_smile:

I don’t think Kenai is doing you any favors. I want to see how it works. I look around in the sources JARs. Why are there so many? I opened 3 or 4 and found only some annotations and interfaces. Ok, then, back to the website. The Kenai website doesn’t really have things readily available. I found a link to some source, clicked on examples, and began expanding a bunch of Maven format directories, waiting for the whole page to refresh (slowly!) with each click. After 8 painfully slow clicks, I find two interfaces: EchoClient and EchoServer. My god this shouldn’t be so hard. Finally I see a “Wiki” link. Wow, useful information at last!

It appears to be an RMI library. Can you serialize types other than primitives, Arrays, Lists, Sets, Maps, and Enumerations? How efficient is the bandwidth usage? How many bytes does it take to call a method with one int parameter that returns an int? Do method invocations on a proxy object block while the remote method is being invoked? Do you support non-blocking? Are you using NIO?

Seemingly hidden at the bottom of the first wiki page is a link to “Documentation”, which takes me to a ton of information. I definitely think you should make this more prominent!

It looks like an interesting library. If I were to sit down and make use of it, I’d read all the documentation, but since I’m just giving it a “once over”, I basically skim the example code. I think I have a reasonably good idea of what you are doing. I think it would help if the example code started simple and built up to the more advanced usage. Currently I feel sort of thrown into the advanced bit before I can really understand what is going on.

[quote]JAR != zip file. I always wonder why people put docs, etc in JARs. :slight_smile:
[/quote]
Good point, I take notes. I should distribute zip files.
Note: the jar files are zip files with a different file name extension. You can rename them to .zip and unzip them.

[quote]I want to see how it works. I look around in the sources JARs. Why are there so many? I opened 3 or 4 and found only some annotations and interfaces.
[/quote]
Jnag is composed of a few modules, you saw 1 jar for each of them. Their content is described at the beginning of the documentation. You probably opened the module that contains the annotations and interfaces that are used to decorate the network interfaces.

[quote]Ok, then, back to the website. I found a link to some source, clicked on examples, and began expanding a bunch of Maven format directories, waiting for the whole page to refresh (slowly!) with each click. After 8 painfully slow clicks, I find two interfaces: EchoClient and EchoServer. My god this shouldn’t be so hard.
[/quote]
The part of Kenai which serve the sources on a per file basis is very slow, you chose the worst way to read the sources. The best way is to use Mercurial and clone the whole repository. The second best way is what you did early, to download the sources from the download section.

[quote]It appears to be an RMI library.
[/quote]
An RPC library, precisely.

[quote]Can you serialize types other than primitives, Arrays, Lists, Sets, Maps, and Enumerations?
[/quote]
Not at the moment, but this is easily to add. (added to the todo list for the 1.2.2 release, thanks).

[quote]How efficient is the bandwidth usage?
[/quote]
The parameters are not currently compressed, but only raw data is transmitted, no type. You also need to count 4 bytes for the target object if you choose to use Jnag without the @Singleton annotation (using the annotation, it is zero bytes), and for the method ID, I would say that in most cases only 1 byte is needed.

[quote]How many bytes does it take to call a method with one int parameter that returns an int? Do method invocations on a proxy object block while the remote method is being invoked? Do you support non-blocking? Are you using NIO?
[/quote]
The library is doing asynchronous messages, they are going in 1 way only, and the program doesn’t block when you call a function on a proxy.

[quote]Seemingly hidden at the bottom of the first wiki page is a link to “Documentation”, which takes me to a ton of information. I definitely think you should make this more prominent!
[/quote]
he he … I am a programmer, not a designer :stuck_out_tongue:

How would you organize it?

[quote]It looks like an interesting library.
[/quote]
It is ;D

[quote]If I were to sit down and make use of it, I’d read all the documentation, but since I’m just giving it a “once over”, I basically skim the example code. I think I have a reasonably good idea of what you are doing. I think it would help if the example code started simple and built up to the more advanced usage. Currently I feel sort of thrown into the advanced bit before I can really understand what is going on.
[/quote]
True. I need to create more samples, 1 for each feature.

I don’t mean to sound harsh, but that is a poor excuse. You don’t have to be a designer to have a good logical design. Just eat your own dog food. When you are looking for something yourself, every once in a while try to find it from the home page and see how easy it is to find. Also take your own experiences when visiting other sites where you want to find libraries. Think what you look for first: examples, docs, sources, license, summary. Those are pretty important and should be made prominant.

Hi Jester,

I reorganized the wiki’s pages. Now the navigation should be more clear. Thx.

Sure, same thing. :slight_smile:

[quote]The parameters are not currently compressed, but only raw data is transmitted, no type. You also need to count 4 bytes for the target object if you choose to use Jnag without the @Singleton annotation (using the annotation, it is zero bytes), and for the method ID, I would say that in most cases only 1 byte is needed.
[/quote]
When using @Singleton, if you just send the method ID, how do you identify what class to invoke the method on?

In my projects I have found the overhead to do RMI to be at least 3 bytes (assuming you write small integers as 1 byte). Here is why:
1 object ID The int ID of the object to invoke a method upon.
1 method class ID The int ID of the class declaring the method to invoke.
1 method index The int index of the method to invoke.
I found that it isn’t enough to just send a method index. On one end of the connection, all I know is that I want to invoke method X on interface Y. On the other side, the class implementing interface Y may also have other methods. I suppose there could be some trickery to make the method ID also identify the declaring class, but even then you’ll have to write two bytes for the method ID once it doesn’t fit in 1 byte (probably > 127, depending on how you compress ints).

If the method returns a non-void value, I also have to send a 1 byte response ID, to know when I receive the return value of the method invocation.

Because of the RMI overhead, while it is very minor, I tend to just send objects in my games and do instanceof checks on the other side to determine what to do with the objects. A bunch of instanceof checks certainly isn’t as nice as being able to call methods remotely, but it does avoid a couple bytes per send (at least in my apps).

[quote]The library is doing asynchronous messages, they are going in 1 way only, and the program doesn’t block when you call a function on a proxy.
[/quote]
So to get back a value, the other side of the connection would have to explicitly make an RMI call to send the response? How would you correlate the response back to the input? Eg, I think you would have to send an ID along with the input parameters. The response would have to also include the ID, so that you’d know what input parameters the response correlates with. This may be tedious if it is needed often.

Also, you won’t be able to get back a value by remotely invoking methods on 3rd party classes that don’t know how to send back a value through JNAG. You could always wrap them though. Of course, for games you probably never need this.

[quote]True. I need to create more samples, 1 for each feature.
[/quote]
I think you can get away with fewer samples by writing articles that introduce features through sample code. An article starts with a simple example, then iteratively adds functionality to it, introducing and explaining new features at each step. Maybe an article like this on how to build a simple chat application using JNAG would cover nearly all of the features?

[quote]I reorganized the wiki’s pages. Now the navigation should be more clear. Thx.
[/quote]
Much better! Though I still contend that the “Wiki” link is too hard to find. If someone doesn’t think to click on those four little letters, they’ll never find the nice documentation you’ve written. If it would be possible to move your documentation index to the homepage, that would be ideal.

[quote]When using @Singleton, if you just send the method ID, how do you identify what class to invoke the method on?
[/quote]
In fact, I forgot that I changed the way I encoded the messages a few months ago. Now I send the method ID first, then the target object ID if needed, then the parameters.

The method ID implies the type of the target object. When the count of all the methods of all the network interfaces of the receiver is over 256, then 2 bytes are used for the method ID.

[quote]Because of the RMI overhead, while it is very minor, I tend to just send objects in my games and do instanceof checks on the other side to determine what to do with the objects. A bunch of instanceof checks certainly isn’t as nice as being able to call methods remotely, but it does avoid a couple bytes per send (at least in my apps).
[/quote]
If the object’s type information is sent, then that’s about the same.

[quote]So to get back a value, the other side of the connection would have to explicitly make an RMI call to send the response? How would you correlate the response back to the input? Eg, I think you would have to send an ID along with the input parameters. The response would have to also include the ID, so that you’d know what input parameters the response correlates with. This may be tedious if it is needed often.
[/quote]
Jnag was made for games which are not designed to block on a remote function call (that’s a big difference with RMI). If you want to get an answer, you need the destination to know where to answer. One way is to have the remote object implicitly know where to answer (by program design), and another way is to pass a reference to a callback in the parameter list. If such reference is a singleton, then no additional byte is encoded for this extra parameter.

[quote]Also, you won’t be able to get back a value by remotely invoking methods on 3rd party classes that don’t know how to send back a value through JNAG. You could always wrap them though. Of course, for games you probably never need this.
[/quote]
True, we never need to directly do a remote call to a 3rd party library.

[quote]Much better! Though I still contend that the “Wiki” link is too hard to find. If someone doesn’t think to click on those four little letters, they’ll never find the nice documentation you’ve written. If it would be possible to move your documentation index to the homepage, that would be ideal.
[/quote]
I will try that.

I have made my main wiki page clearer and let it be the project’s landing page. I will release the next version of Jnag using zip files as requested. So far, your feedback were really useful. If you have more critics, they are more than welcome :slight_smile:

Cool, the wiki pages are much easier to find now!

Can you point me to some classes that do network communication?

They all kind of do :slight_smile:

There is a section which explains which module contains what at the beginning of the documentation.

Eh.

I recommend you to try the samples, take a look at the generated files, and trace the code if needed.