socket communications in JFX

Jose Martinez jmartine_1026 at yahoo.com
Mon Aug 13 08:13:01 PDT 2012


Dan,

Thank you for the detailed information.  I never knew you could instantiate an ObjectInputStream from a socket stream.  That seems pretty cool, almost too cool to be true.  Don't know I have not seen this before.  

I will now digest this along with the links Jonathon sent.  

So far what I have had in mind were two asynch conenctions, one for incoming and one for outgoing stuff.  I will try TCP first, and hopefully will not have to dive in to the world of UDP.  Because I am a n00b at multiplayer I designed the multiplayer to be like Puzzlefighter, where the players do not share a common screen.  Basically each player's screen is updating state to the other player.

The JFX OCN forum is kind of dead, I find you guys to be more enlightened and responsive.  I will make an effort to go back to the OCN forum. 
 
thanks
jose


________________________________
 From: Daniel Zwolenski <zonski at gmail.com>
To: Jose Martinez <jmartine_1026 at yahoo.com> 
Cc: "jonathan.giles at oracle.com" <jonathan.giles at oracle.com>; "openjfx-dev at openjdk.java.net" <openjfx-dev at openjdk.java.net> 
Sent: Monday, August 13, 2012 5:46 AM
Subject: Re: socket communications in JFX
 

oops

> Either use two threads (one for asynch events and another for request-response)

That should be use two "sockets" not threads. 



On Mon, Aug 13, 2012 at 7:44 PM, Daniel Zwolenski <zonski at gmail.com> wrote:

Hey guys, 
>
>
>Sorry for the rough reply earlier. This is actually probably a question best for the forums, and if this doesn't provide what you need I'd suggest moving the conversation over to there (and let me know, as I don't hit the forums as often as I'd like to).
>
>
>The Worker/Task/Service stuff is useful when your action originates from within the UI (such as from a Button click) and you then want to do a long running task (like sending data to the server). 
>
>
>For listening to asynchronous messages from the server (i.e. random events sent down the socket), everything is reversed: your action is triggered by the server and you want to update your UI. For this, I would use a normal Java thread with a loop that reads from the socket's input stream and then "calls out" to your GUI to update it. The call out is the bit that needs to happen in the JFX thread, so you need to wrap this in a Platform.runLater. 
>
>
>Here's some very rough code that does more or less what you want (I've used an ObjectReader and assumed the server is serializing Java Objects down the wire) but you could stream anything (bytes, XML, JSON, etc). 
>
>
>    public void listenToServer() {
>
>
>        try {
>            Socket socket = new Socket("myserver.com", 9000);
>            ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
>
>
>            Object next;
>            while ((next = in.readObject()) != null) {
>                final Object messageFromServer = next;
>                Platform.runLater(new Runnable() {
>                    public void run() {
>                        handleServerMessage(messageFromServer);
>                    }
>                });
>            }
>        } catch (IOException e) {
>            // probably some retry attempts - depends on what you are doing
>        } catch (ClassNotFoundException e) {
>            // server sent a dodgy message
>            e.printStackTrace();
>        }
>    }
>
>
>    public void handleServerMessage(Object messageFromServer) {
>        // you can now update your GUI in the JFX main thread
>        if (messageFromServer instanceof PlayerMoved) {
>            PlayerMoved playerMoved = (PlayerMoved)messageFromServer;
>            playerSprite.moveTo(playerMoved.getX(), playerMoved.getY());
>        } else if (messageFromServer instanceof GameOverMessage) {
>            my.setText("Game Over Man");
>        }
>    }
>
>
>Note that this is for listening (and I'm assuming you are using an asynchronous message approach - where your server can send arbitrary messages at any time). For sending to the server then the Task (or Service) stuff is the way to go. 
>
>
>    public void sendMessageToServer(final Object message) {
>        Task worker = new Task() {
>            protected Object call() throws Exception {
>                // where 'out' is the OutputStream of the Socket
>                out.writeObject(message);
>                return null;
>            }
>
>
>            protected void succeeded() {
>                // message got through, yay
>            }
>
>
>            protected void failed() {
>                // message failed, curse you unreliable internet
>                getException().printStackTrace();
>            }
>        };
>        new Thread(worker).start();
>    }
>
>
>If you want to do synchronous messaging (i.e. where you server responds to the message you sent it), then you need to be careful with threads. The 'succeeded' method above can read the next response from the server, but the other listener thread will likely intercept it first (or you might get a random message coming down while you are waiting for your response). Either use two threads (one for asynch events and another for request-response) or put IDs on your request+response and match them up on the client using queues, etc. 
>
>
>Also use the Task stuff when first setting up your connection to the sever (i.e. when you new the Socket and open the input/output stream). Much the same as above.
>
>
>On a side note, there's some cool stuff with WebSockets now (http://tomcat.apache.org/tomcat-7.0-doc/web-socket-howto.html) if you can use a server new enough. Avoids lots of nasty port/firewall issues. 
>
>
>Oh and also consider Hessian for serializing really nice small data down the wire that can be read by lots of languages (for when you do that iPhone version): http://hessian.caucho.com/
>
>
>
>
>
>
>
>On Mon, Aug 13, 2012 at 2:14 PM, Daniel Zwolenski <zonski at gmail.com> wrote:
>
>Hey Jose, 
>>
>>
>>I will reply properly later when I get home, but in general you can do normal Java socket stuff in JFX2.
>>
>>I wouldn't use the Task/Worker stuff for this but make use of the low-level Platform.runLater method. 
>>
>>i.e. Start a new thread that reads from the thread, when you get some data you want to process just use Platform.runLater()
>>
>>
>>roughly: 
>>
>>
>>new Thread() {
>>
>>
>>   run() {
>>
>>
>>    while (data = socket.readNext()) {
>>
>>
>>        Platform.runLater(new Runabble() {
>>            // update JavaFX UI with 'data' read from socket
>>       }
>>
>>
>>    }
>>
>>
>>
>>
>>  }
>>
>>
>>}
>>
>>
>>
>>
>>
>>On Mon, Aug 13, 2012 at 11:53 AM, Jose Martinez <jmartine_1026 at yahoo.com> wrote:
>>
>>Jonathon,
>>>
>>>Thank you.  I will digest this info and respond back with any questions.
>>> 
>>>jose
>>>
>>>
>>>________________________________
>>> From: Jonathan Giles <jonathan.giles at oracle.com>
>>>To: openjfx-dev at openjdk.java.net
>>>Sent: Sunday, August 12, 2012 9:33 PM
>>>Subject: Re: socket communications in JFX
>>>
>>>
>>>The generally accepted approach is to keep the slow running tasks off of the UI thread (in our case the JavaFX Application Thread). If you don't, you subject the user to a slow user interface, but I'm sure you're well aware of this based on your comments.
>>>
>>>Generally how you approach this is not defined by JavaFX, rather it comes down to how your architecture needs to work. One place to look is the JavaFX Worker and Task API:
>>>http://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm
>>>http://docs.oracle.com/javafx/2/api/javafx/concurrent/Task.html
>>>
>>>-- Jonathan
>>>
>>>On 13/08/2012 1:27 p.m., Jose Martinez wrote:
>>>> Hello,
>>>>
>>>> I am preparing to implement multiplayer capabilities.  Saw one or two articles out there about socket communications and JFX but they were from JFX 1.x.
>>>>
>>>> I guess my first question is, is there a way to communicate from a socket thread directly to the JFX main thread or does the JFX main thread need to poll some shared object?  Is there any recent documentation out there on either the topic of socket communications within JFX or even just multithreading in JFX applications?
>>>>
>>>> thanks!
>>>> jose
>>>
>>
>


More information about the openjfx-dev mailing list