Многофункциональный Java-сервер - PullRequest
0 голосов
/ 30 декабря 2018

Я пишу простой Java-сервер, который соединяет только 5 пользователей и запускает просто игру.Моя проблема в том, чтобы общаться с клиентами, потому что объект Game находится в основном потоке, и каждая отдельная подпотока получает информацию о конкретном движении игрока (1-5 id).Я не знаю, как отправить эту информацию в главную ветку и обновить статус игры.

Правильно ли написан мой код, нет серьезных ошибок (это мой первый проект с многозадачностью), и что я должен был сделать, чтобы общаться с Основным потоком

Player.java

package Model;

import java.io.*;
import java.net.Socket;

public class Player extends Thread{

private long id;
private Socket clientSocket;
private InputStream clientInput;
private BufferedReader clientIn;
private DataOutputStream clientOut;
private String nickname;
private boolean isReady;

public Player(long id, Socket clientSocket) throws IOException {
    this.id = id;
    this.clientSocket = clientSocket;
    this.clientInput = this.clientSocket.getInputStream();
    this.clientIn = new BufferedReader(new InputStreamReader(this.clientInput));
    this.clientOut = new DataOutputStream(this.clientSocket.getOutputStream());
    this.isReady = false;
    clientOut.writeBytes("POLACZONO\n");
    clientOut.flush();
}

public void run() {
    boolean isCorrect = false;
    try {
        while(!isCorrect) {
            String login = this.clientIn.readLine();
            if (!login.equals("") && login.startsWith("LOGIN") && login.length() > 6) {
                this.clientOut.writeBytes("OK\n");
                this.clientOut.flush();
                setNickname(login.substring(login.indexOf(" ") + 1));
                isCorrect = true;
                this.isReady = true;
            } else if (!login.equals("") && (!login.startsWith("LOGIN") || login.length() <= 6)) {
                this.clientOut.writeBytes("ERROR\n");
                this.clientOut.flush();
            }
        }

        while (true) {
            //DATA FROM CLIENT
        }
        //this.clientOut.writeBytes("START " + this.id + " " + startPlayer + "\n");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            this.clientSocket.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

Основная тема

public void startServer(ServerSocket serverSocket) throws IOException {
        playerList = Collections.synchronizedList(new ArrayList<Player>());

        int remaining = 1;
        while (true) {
            if(playerList.size() < 5) {
                while (playerList.size() < 5) {
                    Socket connectionSocket = serverSocket.accept();
                    playerList.add(new Player(remaining, connectionSocket));
                    playerList.get(playerList.size() - 1).start();
                    remaining++;
                }
            }

            final int startPlayer;

            if(!playerList.stream().noneMatch(x -> x.isReady())) {
                startPlayer = new Random().nextInt((5 - 1) + 1) + 1;
                for (Player player : playerList) {
                    player.getClientOut().writeBytes("START " + player.getId() + " " + startPlayer + "\n");
                }
                //GAME START
            }
        }
    }

1 Ответ

0 голосов
/ 01 января 2019

Хорошо, это означает, что вы использовали один поток на пользователя для чтения данных и только один поток для отправки данных пользователям!В основном потоке вы можете использовать LinkedBlockingQueue и передавать эту очередь потокам читателей!Каждый раз, когда пакет получен, вы можете поместить его в очередь и перенести в основной поток!Итак, вы должны написать это в своей ветке чтения:

queue.put(data);

И это в основном потоке:

data = queue.take();

Эта очередь является поточно-ориентированной, так что это означает, что многопоточность может помещать и принимать данные!Метод take блокирует поток до тех пор, пока данные не будут помещены в очередь.

...