Я работаю над карточной игрой типа MTG / Hearthstone, но у меня возникают проблемы со связью между Сервером и Клиентом.
Я уже посмотрел учебники и проекты, но они пока не помогли.Клиент часто зависал или неправильно настроен в контроллере.
Сервер:
package server;
import game.GameData;
import game.PlayerData;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class ServerTest implements Runnable {
private int port;
private boolean running, gameStarted;
private ArrayList<Socket> players;
private GameData gameData;
public ServerTest(int port){
this.port = port;
this.running = false;
this.gameStarted = false;
gameData = new GameData();
}
public Socket waitForConnection(ServerSocket serverSocket) {
try {
Socket socket = serverSocket.accept();
PlayerData playerData = readData(socket);
System.out.println("Player connected: " + playerData.getName());
gameData.getPlayers().add(playerData);
sendData(socket, playerData);
return socket;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public PlayerData readData(Socket socket){
try {
ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
return (PlayerData) objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public void sendData(Socket socket, PlayerData playerData){
try {
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writeObject(playerData);
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stop() {
running = false;
}
@Override
public void run() {
running = true;
int counter = 0;
try {
ServerSocket serverSocket = new ServerSocket(port);
players = new ArrayList<Socket>();
while (running) {
if(!gameStarted) {
if (gameData.getPlayers().size() < 2) {
players.add(waitForConnection(serverSocket));
}
if (gameData.getPlayers().size() == 2) {
gameData.drawCards();
gameData.getPlayers().get(0).setOpponent(gameData.getPlayers().get(1));
gameData.getPlayers().get(1).setOpponent(gameData.getPlayers().get(0));
gameData.getPlayers().set(0, readData(players.get(0)));
gameData.getPlayers().set(1, readData(players.get(1)));
sendData(players.get(0), gameData.getPlayers().get(0));
sendData(players.get(1), gameData.getPlayers().get(1));
gameStarted = true;
gameData.getPlayers().get(0).setStarted(true);
gameData.getPlayers().get(1).setStarted(true);
System.out.println("Game started");
}
} else {
Thread.sleep(500);
gameData.getPlayers().set(0, readData(players.get(0)));
gameData.getPlayers().set(1, readData(players.get(1)));
gameData.getPlayers().get(0).setOpponent(gameData.getPlayers().get(1));
gameData.getPlayers().get(1).setOpponent(gameData.getPlayers().get(0));
sendData(players.get(0), gameData.getPlayers().get(0));
sendData(players.get(1), gameData.getPlayers().get(1));
/*
sendData(players.get(counter), gameData.getPlayers().get(counter));
gameData.getPlayers().set(counter, readData(players.get(counter)));
if(counter == 0) {
gameData.getPlayers().get(1).setOpponent(gameData.getPlayers().get(0));
sendData(players.get(1), gameData.getPlayers().get(1));
counter = 1;
} else {
gameData.getPlayers().get(0).setOpponent(gameData.getPlayers().get(1));
sendData(players.get(0), gameData.getPlayers().get(0));
counter = 0;
}*/
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Клиент:
package client;
import game.GameData;
import game.PlayerData;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientTest implements Runnable{
private int port;
private String host;
private PlayerData playerData;
private GameData gameData;
private Socket socket;
private boolean running;
public ClientTest(int port, String host, String name) {
this.port = port;
this.host = host;
playerData = new PlayerData(name);
running = false;
}
public void connectToServer(){
try {
socket = new Socket(host, port);
sendPlayerData(socket, playerData);
readGameData(socket);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void disconnectFromServer(){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendPlayerData(Socket socket, PlayerData playerData){
try {
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writeObject(playerData);
outputStream.flush();
} catch (IOException e) {
disconnectFromServer();
}
}
public PlayerData readGameData(Socket socket){
try {
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
return (PlayerData) inputStream.readObject();
} catch (Exception e) {
disconnectFromServer();
} return null;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public PlayerData getPlayerData() {
return playerData;
}
public void setPlayerData(PlayerData playerData) {
this.playerData = playerData;
}
public GameData getGameData() {
return gameData;
}
public void setGameData(GameData gameData) {
this.gameData = gameData;
}
public Socket getSocket() {
return socket;
}
public void setSocket(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
running = true;
connectToServer();
while (running){
while (!playerData.isStarted()) {
sendPlayerData(socket, playerData);
readGameData(socket);
}
//sendPlayerData(socket, playerData);
System.out.println("Read...");
PlayerData data;
while ((data = readGameData(socket)) != null) {
playerData = data;
}
}
}
}
Так я устанавливаю PlayerDataв Контроллере:
public void setLoginData(String name, String ip, int port){
Platform.runLater(() -> {
client = new ClientTest(port, ip, name);
System.out.println(client.getPlayerData().getName());
Thread inputThread = new Thread(client);
inputThread.start();
myName.setText(client.getPlayerData().getName());
});
}
Я ожидаю, что Сервер сначала установит обоих игроков, затем будет ждать, пока первый Клиент отправит данные и установит новые данные для обоих игроков.
Заранее спасибо!