Я хочу сделать небольшую игру для Android, в которой один человек является хостом (сервер веб-сокета), а тот же человек и другие являются клиентами (клиент веб-сокета).
Я использую библиотеку Java-WebSocket от TooTallNate для клиента и сервера.
У меня есть два мобильных телефона, один с сервером веб-сокетов, созданный со следующим uri: «ws://localhost:port», а другой с клиентом веб-сокета, подключающимся к «ws://my_public_ip:port».
Я пробовал несколько портов, которые нашел в Интернете, и несколько комбинаций с WIFI и 3G, локальным хостом или моим общедоступным IP-адресом, и все закончилось отказом в соединении или тайм-аутом.
Я знаю, что клиентская сторона работает, потому что мне удалось подключиться к эхо-серверу websocket.
Это должно работать как минимум через WIFI и неплохо бы и через 3G.
Какие IP-адреса и порты следует использовать на стороне сервера и клиента?
Нужно ли открывать какие-либо порты?
Приведенный ниже код представляет собой серверную и клиентскую реализацию библиотеки, единственная разница с моим проектом заключается в том, что вместо основного метода java я вызываю те же строки в методе onCreate активности Android в потоке, отличном от основной поток.
Реализация библиотеки на стороне сервера:
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
public class SimpleServer extends WebSocketServer {
public SimpleServer(InetSocketAddress address) {
super(address);
}
@Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
conn.send("Welcome to the server!"); //This method sends a message to the new client
broadcast( "new connection: " + handshake.getResourceDescriptor() ); //This method sends a message to all clients connected
System.out.println("new connection to " + conn.getRemoteSocketAddress());
}
@Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
System.out.println("closed " + conn.getRemoteSocketAddress() + " with exit code " + code + " additional info: " + reason);
}
@Override
public void onMessage(WebSocket conn, String message) {
System.out.println("received message from " + conn.getRemoteSocketAddress() + ": " + message);
}
@Override
public void onMessage( WebSocket conn, ByteBuffer message ) {
System.out.println("received ByteBuffer from " + conn.getRemoteSocketAddress());
}
@Override
public void onError(WebSocket conn, Exception ex) {
System.err.println("an error occured on connection " + conn.getRemoteSocketAddress() + ":" + ex);
}
@Override
public void onStart() {
System.out.println("server started successfully");
}
public static void main(String[] args) {
String host = "localhost";
int port = 8887;
WebSocketServer server = new SimpleServer(new InetSocketAddress(host, port));
server.run();
}
}
Реализация библиотеки на клиентской стороне:
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.handshake.ServerHandshake;
public class EmptyClient extends WebSocketClient {
public EmptyClient(URI serverUri, Draft draft) {
super(serverUri, draft);
}
public EmptyClient(URI serverURI) {
super(serverURI);
}
@Override
public void onOpen(ServerHandshake handshakedata) {
send("Hello, it is me. Mario :)");
System.out.println("new connection opened");
}
@Override
public void onClose(int code, String reason, boolean remote) {
System.out.println("closed with exit code " + code + " additional info: " + reason);
}
@Override
public void onMessage(String message) {
System.out.println("received message: " + message);
}
@Override
public void onMessage(ByteBuffer message) {
System.out.println("received ByteBuffer");
}
@Override
public void onError(Exception ex) {
System.err.println("an error occurred:" + ex);
}
public static void main(String[] args) throws URISyntaxException {
WebSocketClient client = new EmptyClient(new URI("ws://localhost:8887"));
client.connect();
}
}
Изменить 25 августа 2019 г.
Я установил сканер портов на устройстве Android. и мог проверить, открыты ли порты, вот шаги, которые я выполнил, все подключено через WIFI:
- Установить сканер портов
- Проверьте 127.0.0.1 (localhost) и порт 8080, результат: открыто 0 портов
- Запустите приложение с сервером веб-сокетов и запустите его.
- Проверьте 127.0.0.1 (localhost) и порт 8080, результат: Порт 8080 ОТКРЫТ: Альтернативный HTTP (я не знал, что вам нужно запустите сервер, чтобы порт был открыт, я думал, что настройки проброса портов роутера должно быть достаточно, я ошибался)
- Проверьте 192.168.1.X (мой частный статический локальный IP-адрес для того же устройства, что и сервер) и порт 8080. Результат: открыто 0 портов.
Я не понимаю, почему порт открыт для локального хоста, а не через частный IP. Мне нужно, чтобы это было открыто для частных и общедоступных IP-адресов. Что мне не хватает?