Десериализация JSON в KryoNet
Пытаюсь написать сервер для онлайн-игры. На данном этапе сервер принимает от клиента координаты игрока и рассылает эти координаты остальным игрокам. В тестовом формате использовал сериализацию Kryo и всё работало отлично, но мне необходимо, чтобы информация в моих пакетах находилась в JSON, поскольку клиентская часть написана на C#. С этим возникают проблемы, а именно сервер выкидывает ошибки
09:24 ERROR: [kryonet] Error reading TCP from connection: Connection 1
com.esotericsoftware.kryonet.KryoNetException: Error during deserialization.
at com.esotericsoftware.kryonet.TcpConnection.readObject(TcpConnection.java:141)
at com.esotericsoftware.kryonet.Server.update(Server.java:205)
at com.esotericsoftware.kryonet.Server.run(Server.java:372)
at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: com.esotericsoftware.jsonbeans.JsonException:
at com.esotericsoftware.jsonbeans.Json.readValue(Json.java:800)
at com.esotericsoftware.jsonbeans.Json.fromJson(Json.java:620)
at com.esotericsoftware.kryonet.JsonSerialization.read(JsonSerialization.java:68)
at com.esotericsoftware.kryonet.TcpConnection.readObject(TcpConnection.java:139)
... 3 more
Caused by: java.lang.ClassNotFoundException: Position
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:333)
at com.esotericsoftware.jsonbeans.Json.readValue(Json.java:797)
... 6 more
09:24 INFO: [kryonet] Connection 1 disconnected.
после получения со стороны клиента JSON вида
{
class: Position,
x: 315,
y: 330,
z: 0
}
Класс Position как со стороны клиента, так и со стороны сервера одинаковый(поля публичные, поскольку было подозрение, что десериализация в приватные поля может приводить к ошибкам):
@Data
public class Position {
public int x, y, z;
public Position(){}
}
Код сервера:
import DTOs.Position;
import DTOs.UnitPosition;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.JsonSerialization;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class Servers extends Listener {
private final Map<Integer, Position> messages = new HashMap<>();
private static Server server;
public static void main(String[] args) throws IOException {
int port = 27960;
server = new Server(port, port, new JsonSerialization());
server.bind(port);
server.start();
server.addListener(new Servers());
}
@Override
public void connected(Connection c) {
messages.forEach((id, data) -> server.sendToTCP(c.getID(), new UnitPosition(c.getID(), data)));
}
@Override
public void received(Connection c, Object object) {
if (object instanceof Position) {
Position message = ((Position) object);
messages.put(c.getID(), message);
server.sendToAllExceptTCP(c.getID(), new UnitPosition(c.getID(), message));
}
}
@Override
public void disconnected(Connection c) {
messages.remove(c.getID());
server.sendToAllExceptTCP(c.getID(), c.getID());
}
}
Код клиента:
import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.JsonSerialization;
import com.esotericsoftware.kryonet.Listener;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class MyClient extends Listener {
private final static int tcpPort = 27960;
private final static Client client = new Client(tcpPort, tcpPort, new JsonSerialization());
private final static String ip = "localhost";
private final Map<Integer, UnitPosition> positionMap = new HashMap<>();
private final Random random = new Random();
private Position my;
private static MyFrame frame;
public static void main(String[] args) throws IOException {
client.start();
client.connect(10000, ip, tcpPort);
MyClient myClient = new MyClient();
client.addListener(myClient);
frame = new MyFrame(myClient);
myClient.my = new Position(Math.abs(myClient.random.nextInt() % 400),
Math.abs(myClient.random.nextInt() % 400));
client.sendTCP(myClient.my);
}
@Override
public void received(Connection connection, Object object) {
if (object instanceof UnitPosition) {
UnitPosition now = (UnitPosition) object;
if(now.getId() != connection.getID()) {
positionMap.put(now.getId(), now);
try {
frame.repaint();
} catch (NullPointerException exception) {
System.out.println("Repaint throw nullPointer!");
}
}
} else if(object instanceof Integer){
positionMap.remove(object);
try {
frame.repaint();
} catch (NullPointerException exception) {
System.out.println("Repaint throw nullPointer!");
}
}
}
public Position getMy() {
return my;
}
public Map<Integer, UnitPosition> getPositionMap() {
return positionMap;
}
public void send() {
client.sendTCP(my);
}
}
Ответы (1 шт):
Проблема состояла в том, что класс Position находился в разных пакетах на клиенте и на сервере. При передаче json пакета в переменную class заносится полное имя класса с учётом пакета, поэтому местонахождение передаваемых классов на клиенте и на сервере должно совпадать.