Client Issues

Hey guys,



I’m having three issues with my client program. I’ve found similar cases around the forums, but nothing that completely applies, and no fixes I’ve tried so far have been any help.


  1. In the IDE, I can open/close my client program easily. I do note, however, that when I press “ESC” the program does not end, only the window closes. Now that I’m at a stage where I can create a distributable file for my client, I’m noticing a glitch that I can only imagine is connected to that. I can run it once. After the window is closed, it will not open again. Furthermore, upon trying to delete associated files, it informs me that they are in use by Java, yet I do not see the program running in Task Manager. What is the proper way to Close a connection and its associated window? As I said, I’ve tried the tutorial solution to no avail. I have seen, though, that SpiderMonkey can be temperamental, so I thought someone here might have figured this out.



    Current Code: (thisClient is the client that the program creates)

    [java]if (thisClient == null) {



    thisClient.close();

    destroy();



    }[/java]




  2. Clients outside my network cannot connect to my server. Yes, I have the proper ports forwarded, and no, I am not using my local IP. The outside clients also forwarded the port being used to ensure that was not the cause. Is there a way to check which IP the server is using to host? I notice that I cannot connect using my external IP address. It only seems to work with “localhost”, “127.0.0.1”, and my local IP.



    If you would like to see any reference code, let me know.




  3. The third issue is something I intend to research more, but I figured I’d include it here since I was making the post. When I run my client, I get no settings menu. It automatically opens a window with the minimum settings. Is there a way to open the settings menu manually?



    If you would like to see any reference code, let me know.





    Thanks for any help you can give!
  • Dan
@danoso42 said:
Hey guys,

I'm having three issues with my client program. I've found similar cases around the forums, but nothing that completely applies, and no fixes I've tried so far have been any help.

1) In the IDE, I can open/close my client program easily. I do note, however, that when I press "ESC" the program does not end, only the window closes. Now that I'm at a stage where I can create a distributable file for my client, I'm noticing a glitch that I can only imagine is connected to that. I can run it once. After the window is closed, it will not open again. Furthermore, upon trying to delete associated files, it informs me that they are in use by Java, yet I do not see the program running in Task Manager. What is the proper way to Close a connection and its associated window? As I said, I've tried the tutorial solution to no avail. I have seen, though, that SpiderMonkey can be temperamental, so I thought someone here might have figured this out.


Temperamental in what way? I run a SM based server 24 hours a day without problems.

@danoso42 said:
Current Code: (thisClient is the client that the program creates)
[java]if (thisClient == null) {

thisClient.close();
destroy();

}[/java]


Where have you put this code?

@danoso42 said:
2) Clients outside my network cannot connect to my server. Yes, I have the proper ports forwarded, and no, I am not using my local IP. The outside clients also forwarded the port being used to ensure that was not the cause. Is there a way to check which IP the server is using to host? I notice that I cannot connect using my external IP address. It only seems to work with "localhost", "127.0.0.1", and my local IP.

If you would like to see any reference code, let me know.


It sounds like a firewall issue. Make sure that both UDP and TCP can get through on the port(s) you have specified. SpiderMonkey should bind to all of the network interfaces but it would be surprising if you had more than one interface to bind to. Most of the time I've seen this seems to be when the local firewall or the router are blocking UDP on that port.

You can test for this case by temporarily disabling UDP when you create your server and client. Just pass -1 for the UDP port on both ends.

If that still doesn't work then see if you can telnet to the TCP port. If your network is setup then you should be able to connect with telnet. If you can't even connect with telnet then there is still a problem with your setup somewhere that is probably not related to SpiderMonkey.

@danoso42 said:
3) The third issue is something I intend to research more, but I figured I'd include it here since I was making the post. When I run my client, I get no settings menu. It automatically opens a window with the minimum settings. Is there a way to open the settings menu manually?


Sounds like you have set show settings to false: http://hub.jmonkeyengine.org/javadoc/com/jme3/app/SimpleApplication.html#setShowSettings(boolean)

Setting that to false prevents the settings dialog from coming up and then you'd have to set all of your application settings manually in code.
1 Like

Thanks for the speedy reply!



1) Temperamental as in the documentation for it is outdated and scattered around, not as in performance.



That code appears just after:

[java]try {



thisClient = Network.connectToServer(HOST_IP, HOST_PORT);

thisClient.start();

System.out.println("[Info] Client connected.");



}catch(IOException e) {



System.out.println(“IOException e caught (in MyGameClient)!”);



}[/java]



When the client ran and found no server, I would get a null pointer exception.







2) I’ll try modifying my firewall and trying again. Thanks!







3) Is this the correct way to do it? Seems to have no effect. (MyGameClient extends SimpleApp)

[java]MyGameClient clientApp = new MyGameClient();



clientApp.setShowSettings(true);



clientApp.start(JmeContext.Type.Display);[/java]





Thank you for your assistance!

@danoso42 said:
Thanks for the speedy reply!

1) Temperamental as in the documentation for it is outdated and scattered around, not as in performance.


I think the trick is just sorting out the old from the new sometimes. I nearly completely rewrote SpiderMonkey about a year ago so some stuff might be old. The TestChatServer and TestChatClient are, together, perhaps the best introduction.

@danoso42 said:
That code appears just after:
[java]try {

thisClient = Network.connectToServer(HOST_IP, HOST_PORT);
thisClient.start();
System.out.println("[Info] Client connected.");

}catch(IOException e) {

System.out.println("IOException e caught (in MyGameClient)!");

}[/java]

When the client ran and found no server, I would get a null pointer exception.


Yeah, because you say: if( client = null ) client.doSomething.... that will always trigger a NullPointerException if the client is null.

You want to make sure to close the client when the application is shutting down. Most of the client-side SM threads are daemon and will automatically shut down with the app but the thread that makes sure messages get written to the socket isn't. I felt it was nicer to the server to be as sure as possible that only complete messages are sent. It's probably just paranoia on my part.

The safest way to make sure networking gets closed when the app closes down is either to do it in the cleanup method of an app state or just override SimpleApplication's destroy() method (make super sure to call super.destroy() though).

In my app, all of my main game logic is in an AppState that gets added as part of network connection setup... so it's easy to close the client down there. Overriding destroy() should do the trick if you aren't already using an app state.

...and you probably want:
[java]
if( client != null ) {
client.close();
}
[/java]

Note the "not equal" instead of "equal".
1 Like
@pspeed said:
...and you probably want:
[java]
if( client != null ) {
client.close();
}
[/java]

Note the "not equal" instead of "equal".


The issue was the code would start running even if a connection wasn't made, so I created that to shut down the program if the Client was still, in fact, null. I do see what you mean though with my call of "thisClient.close();", so thank you for pointing that out. Even when the client is null, though, the application doesn't want to close after it's been Exported from the IDE. And when it is null, I can't call client.close().
@danoso42 said:
The issue was the code would start running even if a connection wasn't made, so I created that to shut down the program if the Client was still, in fact, null. I do see what you mean though with my call of "thisClient.close();", so thank you for pointing that out. Even when the client is null, though, the application doesn't want to close after it's been Exported from the IDE. And when it is null, I can't call client.close().


Yeah, if there is no connection then there is nothing to close on the networking side.

What method are you in when you are trying to connect? Can I see more of your code because the little snippets make it harder to see what's happening?

At any rate, destroy() is not what you want to call to shut down a JME application. stop() is what you want.
1 Like

And you can just call stop() in the catch( IOException ) block if you want to shutdown on network error.

1 Like

Alright. Thank you for clearing that up for me. I have it working nicely now, and it closes up as it’s supposed to.



I still haven’t been able to test our client connection properly, but I’m sure I can clear that up.



I wasn’t able to get the settings window to load up, but I did figure out how to configure it manually, which is more what I was looking for anyway.



Now I just need to work my way around some “Problem spatial name: Root Node” errors.





You have been a great help. Thank you for your assistance!

-Dan

@danoso42 said:

3) Is this the correct way to do it? Seems to have no effect. (MyGameClient extends SimpleApp)
[java]MyGameClient clientApp = new MyGameClient();

clientApp.setShowSettings(true);

clientApp.start(JmeContext.Type.Display);[/java]


And by the way, the only thing I see different than what I do is that I don't pass an argument to start() and I set the settings right before start().

[java]
MainStart app = new MainStart();

AppSettings settings = new AppSettings(false);
settings.setTitle( "Mythruna RCG v0.1" );
settings.setSettingsDialogImage( "/Interface/mythruna-title.png" );
app.setSettings( settings );
app.start();
[/java]

...and I get the settings dialog pop-up during launch.

I tried that configuration, and it’s still not showing up for me. As I said though, I’m fine with having it set manually. Thanks, though.



I didn’t realize you were the developer for Mythruna. That’s some very nice work. I was taking a look at it a few days ago.



I have one other problem you may have some insight into. I am continually running into errors of various types. They are different each time I run the application. Sometimes it works perfectly. Sometimes I get a null pointer error with my Physics. Sometimes I get a “Problem spatial name: Root Node” error.

There doesn’t seem to be a pattern to it. It almost seems as though my code isn’t running in order. For example, I call a method to set up my Terrain, and then a method that sets up Physics using the terrain. Occasionally, my Physics method throws a null pointer error on my terrain, and other times it does not.

My terrain setup method is very similar to the one in the tutorial, as is my physics setup method. They are both called in simpleInitApp(), after a server connection has been made (I send information from the server to create the terrain).

Other times I get bulletPhysics errors that don’t seem to originate in my code.

I will just point out that all networking is done on a separate thread… so any messages you receive, the listener is being called on a different thread and you will have to deal with that issue if you want it to interact with the regular application.

1 Like

Thank you for the assistance, but I found the issue elsewhere.



I had three calls in my code to get information from the server by sending out a message. For the sake of simplicity, let’s call them ONE, TWO, and THREE. For TWO to run, ONE needed to be complete. For THREE to run, TWO needed to be complete. I was sending all these calls at the same time, but due to the processes needed to complete them, etc, TWO was finishing after ONE, THREE was finishing before TWO, and so on. I fixed it by changing my code structure.



Thanks for all the help, once again.

1 Like