私はマルチプレイヤー ゲームを作成しており、ソケットを使用して Java で独自のサーバーを作成しています。
Javaチュートリアルといくつかのグーグルを使用してサーバーを正常に稼働させることができましたが、複数のクライアントを処理するためにマルチスレッドサーバーを実装しようとすると、うまく機能しません.
接続する最初のクライアントは引き続き正常に動作しますが、接続する他のクライアントはそのまま待機し、サーバーに入力を送信した後は何もしません。これが私のコードです:
//This class handled Server/client communication for one client.
public class GameRoom implements Runnable {
public GameRoom(Socket socket) {
this.socket = socket;
}
public void run() {
logger.info("Game room has been created.");
while(true) {
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
String clientResponse = in.readLine();
out.println("You wrote " + clientResponse);
out.flush();
} catch (IOException e) {
logger.severe(e.getMessage());
throw new RuntimeException();
}
}
}
//Will eventually change the string to a GSON object and delegate the appropriate actions based on the gson object type.
private String delegateClientInput(String clientInput) {
return "I heard you say: " + clientInput + "\n";
}
private BufferedReader in;
private PrintWriter out;
private Socket socket;
private static final Logger logger = LogUtil.initializeServerLog(GameRoom.class.toString());
}
/*
* This class houses the server socket itself. Handles connecting to multiple clients.
*/
public class ServerClientThreadPool extends Thread {
public static void main(String[] args) {
ServerClientThreadPool serverClientThreadPool = new ServerClientThreadPool();
serverClientThreadPool.startServer();
}
ServerClientThreadPool() {
try {
serverListener = new ServerSocket(GAME_ROOM_PORT);
} catch (IOException e) {
logger.severe(e.getMessage());
throw new RuntimeException();
}
}
public void startServer() {
for(int i = 0; i < MAX_CONNECTIONS; i++) {
try {
GameRoom gameRoom = new GameRoom(serverListener.accept());
gameRoom.run();
} catch (IOException e) {
logger.severe(e.getMessage());
throw new RuntimeException();
}
}
}
private static final int GAME_ROOM_PORT = 18000;
private ServerSocket serverListener;
private static final int MAX_CONNECTIONS = 100;
private static final Logger logger = LogUtil.initializeServerLog(ServerClientThreadPool.class.getName());
}
もちろん、別のプログラムに格納されているクライアントのメイン関数は次のとおりです。
ClientSocketWrapper clientSocketWrapper = ClientSocketWrapper.createSocketWrapperAndConnectTo("localhost", 18000);
/** MAIN ENTRY POINT FOR CLIENT */
while(true) {
clientSocketWrapper.updateInputOutputStream();
clientSocketWrapper.writeToOutputStream(executeClientInputProcessing());
updateGameState(clientSocketWrapper.getServerResponse());
}
これらのメソッドの内部で何が起こっているのかを実際に見ることはできませんが、基本的には Java チュートリアルのようにクライアント側を実装するだけであり、期待どおりに機能します。ここで実行されているメソッドを投稿する必要があると思われる場合はお知らせください。ただし、問題はサーバー側にあると思います。
BONUS QUESTION: ここで正しい軌道に乗っているかどうかも疑問です。ゲームはかなり複雑ですが、Gson を使用してオブジェクトをシリアライズおよびデシリアライズし、送受信される gson 文字列に基づいて適切なアクションを委任するつもりでした。サーバー/クライアント アーキテクチャをグーグルで調べたところ、私のアプローチは単純すぎるようです。より高度なサーバー/クライアント アーキテクチャを学習するための適切なリソースを見つけるのに苦労しているので、優れた書籍やチュートリアルへのリンクがあれば大きな助けになります。
皆さんありがとう!