Проблемы с подключением Kryonet Client Java

У меня есть клиент/сервер kryonet, который работает... в основном. Клиент остается бездействующим и в конце концов отключается через некоторое время, но это не проблема, которую я пытаюсь решить в настоящее время. В настоящее время сервер и клиент могут устанавливать соединение и отправлять данные туда и обратно (до истечения времени ожидания клиента), если клиент и сервер находятся на одном компьютере. Если вы попытаетесь подключиться к другому компьютеру в локальной сети, время ожидания соединения прервется и произойдет сбой.

Итак, вот мой вопрос (ы):

  1. Что может быть возможной причиной проблемы с подключением?

  2. Как правильно сохранить клиента? (второстепенная цель, но если вы ее знаете, это было бы здорово)

*Для этого я использую LibGDX и Kryonet. Насколько я знаю, конфликтов быть не должно.

Сервер:

package com.me.mygdxgame;
import java.io.IOException;
import java.util.ArrayList;

import com.badlogic.gdx.math.Vector2;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.esotericsoftware.kryonet.Server;
import com.me.mygdxgame.Network.Obstacles;

public class GameServer {
    Server server;

    public GameServer () throws IOException {
        server = new Server() {
            protected Connection newConnection () {
                return new PlayerConnection();
            }
        };
        Network.register(server);


        //Sends Stuff to Client
        server.addListener(new Listener() {
            public void received (Connection c, Object object) {
                PlayerConnection connection = (PlayerConnection)c;

                if (object instanceof Obstacles) {
                    if (connection.name != null) return;
                    ArrayList<Vector2> obs = ((Obstacles)object).obstacles;
                    if (obs == null) return;
                    System.out.println("Obstacles recieved.");
                    for(int i = 0; i < obs.size(); i++) 
                        System.out.println("Obstacle " + i + "- x: " + obs.get(i).x  );
                    return;
                }
            }
        });


        server.bind(Network.port);
        server.start();

    }

    public void sendAll () { //Send out data
        Obstacles ob = new Obstacles();
        ob.obstacles = new ArrayList<Vector2>();
        for(int i =0; i < Map.obstacles.size(); i++){
            ob.obstacles.add(new Vector2(Map.obstacles.get(i).x,Map.obstacles.get(i).y));
        }
        server.sendToAllTCP(ob);
    }

    static class PlayerConnection extends Connection {
        public String name;
    }
}

Клиент:

package com.me.mygdxgame;

import java.awt.EventQueue;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;

import com.badlogic.gdx.ApplicationListener;
import com.esotericsoftware.kryonet.Client;
import com.esotericsoftware.kryonet.Connection;
import com.esotericsoftware.kryonet.Listener;
import com.me.mygdxgame.Network.Obstacles;

public class GameClient implements ApplicationListener{
    Client client;
    String name;
    String RefreshHost;
    boolean Connected = false;
    ArrayList<String> hosts = new ArrayList<String>();
    public static String host;

    public GameClient (String host) {
        client = new Client();
        client.start();
        this.host = host;

        Network.register(client);

        client.addListener(new Listener() {
            public void connected (Connection connection) {
                System.out.println("connected");
                Connected = true;
            }

            public void received (Connection connection, Object object) {
                if (object instanceof Obstacles) {
                    Obstacles obs = (Obstacles)object;
                    System.out.println("Obstacle recieved on client - " + obs.obstacles.size());
                    client.sendTCP(obs);
                    System.out.println("Obstacles sent back.");
                    return;
                }else {
                    System.out.println("invalid packet");
                }
            }

            public void disconnected (Connection connection) {
                EventQueue.invokeLater(new Runnable() {
                    public void run () {
                        System.out.println("closed");
                        Connected = false;
                        client.close();
                    }
                });
            }
        });

        new Thread("Connect") {
            public void run () {
                try {
                    client.connect(5000, GameClient.host, Network.port);
                    System.out.println("Connected!");
                    client.setKeepAliveTCP(NORM_PRIORITY);
                    while(Connected) {
                        //System.out.println(client.isIdle());
                    }
                    client.run();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }.start();
    }

    @Override
    public void create() {
        // TODO Auto-generated method stub

    }

    @Override
    public void resize(int width, int height) {
        // TODO Auto-generated method stub

    }

    @Override
    public void render() {
        // TODO Auto-generated method stub

    }

    @Override
    public void pause() {
        // TODO Auto-generated method stub

    }

    @Override
    public void resume() {
        // TODO Auto-generated method stub

    }

    @Override
    public void dispose() {
        // TODO Auto-generated method stub

    }
}

person Chris    schedule 07.10.2013    source источник


Ответы (2)


Я предлагаю вам установить хост ДО того, как вы запустите клиент

   public GameClient (String host) {
        client = new Client();
        this.host = host;
        client.start();

Я не знаком с kryonet Client, но есть смысл сделать это именно так.

Как правило, убедитесь, что ваш клиент пытается подключиться к хосту, на котором работает сервер...

person Germann Arlington    schedule 07.10.2013
comment
Хост на самом деле просто строка, которая используется в client.connect(5000, GameClient.host, Network.port); - person Chris; 08.10.2013
comment
Вы пытались добавить строку вывода отладки, чтобы напечатать адрес, к которому пытается подключиться ваш клиент? System.out.println("Attempting to connect to " + GameClient.host + ":" + Network.port"); незадолго до вашего client.connect(...); - person Germann Arlington; 08.10.2013
comment
Клиент нормально подключается и отправляет данные - person Chris; 08.10.2013
comment
Если вы попытаетесь подключиться к другому компьютеру в локальной сети, время ожидания соединения прервется и произойдет сбой. - что ты имел в виду, чем? - person Germann Arlington; 08.10.2013
comment
Если сервер и клиент находятся на моем компьютере, я могу подключиться. Если его нет на моем компьютере, я не могу подключиться - person Chris; 08.10.2013
comment
Вы пробовали вывод отладки, который я предложил выше? Что он печатает? Я подозреваю, что значение по умолчанию для хоста (IP) может быть localhost, и в этом случае он будет подключаться, когда вы работаете на одном компьютере, и не будет работать на разных компьютерах. - person Germann Arlington; 08.10.2013

Одной из возможных причин такой проблемы с подключением является брандмауэр, блокирующий ваш Network.port.

Еще один, извините, но я должен спросить: работает ли серверное приложение на другой машине?

Я спрашиваю, потому что не вижу основной функции в коде вашего сервера.

public static void main(String[] args) throws IOException {
        Log.set(Log.LEVEL_DEBUG);
        new GameServer();
    }

Я использую для запуска своего серверного приложения эту команду терминала

java -jar myserverfile.jar 

Как заставить его работать на «удаленном» компьютере?

Кстати, я использую libgdx и kryonet для своей игры, и до сих пор у меня не было проблем с их совместным использованием.

В моем случае у меня есть сервер в экземпляре AWS, прослушивающий тестирование игрового клиента с моего компьютера.

person Erick Romero    schedule 29.04.2015