How to facilitate communication between server thread and multiple client threads in Java

I am trying to create a client server game using java sockets. I have a thread server that controls the logic of the game. I also have client streams that interact with the server. I use multiple client handler threads to facilitate server-to-server communication. I use multiple threads to communicate with other client threads using sockets.

Now I am having a problem in how to facilitate communication between a server thread and multiple client streams. For example, should the server select the next player to play, how should it signal the client handler thread and, in turn, communicate with the client thread through sockets?

+3
source share
3 answers

I have done this before, as follows. I have a server socket

    public Server(int port, int numPlayers) {
    game = new PRGameController(numPlayers);

    try {

        MessageOutput.info("Opening port on " + port);
        ServerSocket clientConnectorSocket = new ServerSocket(port);
        MessageOutput.info("Listening for connections");

        while (!game.isFull()) {
            // block until we get a connection from a client
            final Socket client = clientConnectorSocket.accept();
            MessageOutput.info("Client connected from " + client.getInetAddress());

            Runnable runnable = new Runnable() {
                public synchronized void run() {
                    PRGamePlayer player = new PRGamePlayer(client, game);
                }
            };
            new Thread(runnable).start();
        }
    } catch (IOException io) {
        MessageOutput.error("Server Connection Manager Failed...Shutting Down...", io);
        // if the connection manager fails we want to closedown the server
        System.exit(0);
    }
}

Then on the client side I have something like this.

public void connect(String ip) {

        try {
            comms = new Socket(ip, 12345);
            comms.setTcpNoDelay(true);
             // get the streams from the socket and wrap them round a ZIP Stream
            // then wrap them around a reader and writer, as we are writing strings
             this.input =  new CompressedInputStream(comms.getInputStream());
             this.output = new CompressedOutputStream(comms.getOutputStream());
             this.connected = true;
             startServerResponseThread();

        } catch (IOException e) {
            ui.displayMessage("Unable to connect to server, please check and try again");
            this.connected = false;
        }

        if (connected) {
            String name = ui.getUserInput("Please choose a player name");
            sendXML(XMLUtil.getXML(new NameSetAction(name, Server.VERSION)));
        }
    }

    /**
    * This method sets up the server response thread. The thread, sits patiently
    * waiting for input from the server, in a seperate thread, so not to hold
    * up any client side activities. When data is recieved from the server
    * it is processed, to perform the appropriate action.
    */
   public void startServerResponseThread() {

      // create the runnable that will be used by the serverListenerThread,
      // to listen for requests from the server
      Runnable runnable = new Runnable() {

         public void run () {

            try {
               // loop forever, or until the server closes the connection
               while (true) {

                  processRequest(input.readCompressedString());
               }
            } catch (SocketException sx) {
               MessageOutput.error("Socket closed, user has shutdown the connection, or network has failed");
            } catch (IOException ex) {
               MessageOutput.error(ex.getMessage(), ex);
            } catch (Exception ex) {
               MessageOutput.error(ex.getMessage(), ex);
            } finally {
               (PRClone.this).connected = false;
               // only shutdown the server if the listener thread has not already been
               // destroyed, otherwise the server will have already been shutdown
               if (serverListenerThread != null) {
                  // shutdown the thread and inform the application the communications has closed
                  MessageOutput.debug("Shutting down server listener Thread");
               }
            }
         }
      };

      // create the thread
      serverListenerThread = new Thread(runnable);
      // start the thread
      serverListenerThread.start();

   }

The client can send requests to the server through the output stream and read server data from the input stream.

The server can receive requests from the client and process it in the GameController, as well as send notifications from the server using the output stream again to the GameController.

EDIT: In addition, I should note that all my communication is done through XML, and the controller on the client or server decodes the XML and makes the corresponding request.

Hope this helps. This certainly does the job for me and allows my multiplayer games to work well.

+4

, . "" , thread.interrupt(). ( , InterruptedException.)

, java.nio Selector . , . , .

+1

, , ActiveMQ, , , .

. , , . .

. ( ) , . Socket BlockingQueue, , .

0

Source: https://habr.com/ru/post/1767746/


All Articles