Помогите Как отправлять и принимать запросы

  • Автор темы Автор темы Swaimer
  • Дата начала Дата начала

Swaimer

Активный участник
Пользователь
Баллы
61
Как допустим из другого приложение java отправить запрос серверу, и ответить на него. Например если я сделаю лаунчер, у меня есть свой плагин на тех работы, и как из лаунчера отправить запрос серверу, что-бы плагин его принял, обработал и ответил и лаунчер понял, ведутся ли технические работы, как это сделать? И возможно ли это вообще? Если это не возможно, то хоть есть альтернативные варианты?
 
Предлагаю поднять сервер на сокетах прямо внутри плагина. Внутренний сервер будет использовать тот же IP, что и сервер майнкрафт, но работать на другом порту.

И так,
Код:
import org.bukkit.plugin.java.JavaPlugin;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;


public class Main extends JavaPlugin {
    @Nullable
    private AsyncInternalDataServer dataServer;

    @Override
    public void onEnable() {
        try {
            Test test = new Test();
            test.setEnabled(true);
            this.dataServer = new AsyncInternalDataServer(53086, test);
            // Первый параметр - порт, второй - класс, реализующий Switchable
           // (из него берется значение для отправки)

            this.dataServer.start();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }

    @Override
    public void onDisable() {
        if (this.dataServer == null) return;
        try {
            this.dataServer.stop();
            System.out.println("DataServer stopped");
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }

}
Код:
public interface Switchable {
    boolean isEnabled();
}
Код:
public class Test implements Switchable {
    private volatile boolean enabled;

    @Override
    public boolean isEnabled() {
        return enabled;
    }

    synchronized public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
}
Код:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.StandardSocketOptions;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

public class AsyncInternalDataServer {
    private final int port;
    private final Switchable dataHolder;
    private AsynchronousServerSocketChannel serverSocketChannel;
    private boolean running;

    public AsyncInternalDataServer(int port, Switchable dataHolder) {
        this.port = port;
        this.dataHolder = dataHolder;
    }

    public void start() throws IllegalStateException, IOException {
        if (this.running) throw new IllegalStateException("Server is already running");
        else {
            this.serverSocketChannel = AsynchronousServerSocketChannel.open();
            this.serverSocketChannel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
            this.serverSocketChannel.bind(new InetSocketAddress(this.port));
            serverSocketChannel.accept(null,
                    new AcceptCompletionHandler(this.serverSocketChannel, this.dataHolder));
            this.running = true;
        }
    }

    public void stop() throws IllegalStateException, IOException {
        if (!this.running) throw new IllegalStateException("Server is not running yet");
        else {
            this.serverSocketChannel.close();
            this.running = false;
        }
    }

    private static class AcceptCompletionHandler implements CompletionHandler<AsynchronousSocketChannel, Void> {
        private final AsynchronousServerSocketChannel serverSocketChannel;
        private final Switchable dataHolder;

        AcceptCompletionHandler(AsynchronousServerSocketChannel serverSocketChannel, Switchable dataHolder) {
            this.serverSocketChannel = serverSocketChannel;
            this.dataHolder = dataHolder;
        }

        @Override
        public void completed(AsynchronousSocketChannel socketChannel, Void attachment) {
            this.serverSocketChannel.accept(null, this);

            WriteCompletionHandler writeCompletionHandler = new WriteCompletionHandler(socketChannel);
            ByteBuffer buffer;
            synchronized (this.dataHolder) {
                buffer = ByteBuffer.allocate(1).put((byte) (this.dataHolder.isEnabled() ? 1 : 0));
            }
            socketChannel.write((ByteBuffer) buffer.flip(), null, writeCompletionHandler);
        }

        @Override
        public void failed(Throwable exc, Void attachment) {
            if (exc instanceof AsynchronousCloseException) {
                System.out.println("Waiting for an incoming connection canceled : Server closed");
            } else {
                System.err.println("Accepting an incoming connection failed");
                exc.printStackTrace();
            }
        }
    }

    private static class WriteCompletionHandler implements CompletionHandler<Integer, Void> {
        private final AsynchronousSocketChannel socketChannel;

        WriteCompletionHandler(AsynchronousSocketChannel socketChannel) {
            this.socketChannel = socketChannel;
        }

        @Override
        public void completed(Integer result, Void attachment) {
            try {
                this.socketChannel.close();
            } catch (IOException ioException) {
                System.err.println("Cannot close client socket");
                ioException.printStackTrace();
            }
        }

        @Override
        public void failed(Throwable exc, Void attachment) {
            System.err.println("Data sending failed");
            exc.printStackTrace();
        }
    }
}

Это простейший сервер, он просто принимает любые входящие соединения и отправляет 1 или 0 в зависимости от состояния класса, переданного в конструктор сервера.

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

Можно переделать под Netty,
можно использовать Jedis, можно вообще поднять свой HTTP/HTTPS сервер (например Apache, он уже встроен в Spigot (если надо, могу притащить пример Apche HTTPS сервера)), также не забывай про базы данных. В общем, возможностей море - выбери ту, что нравится и вперед!



А вот тут
Код:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class Main {
    public static void main(String[] args) throws IOException {
        System.out.println(isRemoteEnabled("95.82.150.229", 53086));
    }


    public static boolean isRemoteEnabled(String host, int port) throws IOException {
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(host, port));
        ByteBuffer byteBuffer = ByteBuffer.allocate(1);
        socketChannel.read(byteBuffer);
        socketChannel.close();

        return (byteBuffer.get(0) != 0);
    }

}
И да, так как сервер асинхронный - он не будет блокировать основной поток сервера майнрафт, не беспокойся.
В общем, надеюсь было полезно :)
 
Последнее редактирование:
Ну как отправишь так и примешь, тупой вопрос.
 
Назад
Верх