Hello everyone! I have recently started a very ambitious project... I do not know if things will pan out, and I do not wish to hype that which does not exist or make empty promises. BUT, what I do have so far is some bare-bones sockets, a server, a client, and a ton of questions regarding how to go about this efficiently.
For simplicity's sake, everything starts up via the main java project. I suppose I will have to split projects up into server and client once all classes, responsibilities, and interactions are unquestionably nailed down. The flow looks somewhat like this...
run Main JavaFX Project
- create a new Server class running its own thread
- create a ClientDisplay class, which still runs in the javaFX thread
The Server does the following in its run() method:
- creates a new ServerSocket
- creates a new ServerHandler class with its own thread, sending the pointer to itself and the ServerSocket
-The Server class also currently maintains a TreeSet of ServerHandlers which are sorted by player name.
-It will need to hold much more information later on.
The ServerHandler does this in its run() method:
- begins waiting to accept the next socket request from a client
- once it forms a connection, it immediately spins off a new ServerHandler class to begin doing the same and listen for new connections.
- after that, an ObjectInputStream and an ObjectOutputSteam are created with the new socket connection.
- as a test, the ServerHandler begins listening for a specific byte from the client.
- when this byte is received, a sample Player class is created, and the ServerHandler is added to the Server's TreeSet.
- then the Player class is transmitted through the socket back to the client.
The ClientDisplay does this in its run() method:
- create a new ClientHandler class, which runs in its own thread.
- then it does all the normal JavaFX stuff you would expect, creating the window, the stage, drawing, etc.
- additionally, for testing purposes, I have created some eventHandlers that listen for when the arrow keys are pressed or released.
The ClientHandler does this in its run() method:
- attempt to create a new Socket using the correct port that the ServerSocket is listening on.
- create an ObjectOutputStream and ObjectInputStream with the new Socket.
- writes a byte into the stream, then listens to receive a Player object.
Now the thing is, I'm not sure where to go from here. It would seem that I would need all these threads to be waiting idly for when a player inputs something on the client...
For one thing, I am uncertain if it really matters where the Event Handlers are created. After all, java has its own special thread for handling events, doesn't it? Assuming this is the case, there's still a few more design issues.
Once an input is pressed on the keyboard, then a message will need to be sent via the ObjectOutputStream to the ServerHandler. I have heard that when dealing with listeners, you'll want to finish whatever code they are supposed to do as soon as possible so they can begin listening again. And... I am certain a few calculations will happen before the message across the socket is sent and everything is squared away. Some code may even be lengthy. So, would I want to spin off more threads so the input doesn't get blocked?
There's a similar issue with the ServerHandler. I think it is easy enough having it wait to listen for the expected input from a client. Then it just has to interact with the server. And this is where things look ugly, in my opinion. What I'm thinking is that I'd have to have a while loop constantly going around in the server, checking to see if there have been any client inputs/requests. It will be sort of like a stack, and processed on a first come, first served basis when dealing with multiple clients.
When a ServerHandler receives an input from a client, it then might do some final processing, then add the command to that stack of client inputs/requests. The next time the Server goes through its while loop, it will see there is now an item to process and does so, sending information back to all clients that might find the information relevant.
Well... I suppose it might be a way to go about it, though I am concerned about what might happen if the server tried to read the stack at just the wrong time while it was being updated. Would anything be corrupted? Or might java actually be a bit smarter than that? But now that I mention it, I thought I heard something somewhere about multi-threading and locks though I forget the details.