Created
February 20, 2018 21:28
-
-
Save Exerosis/d272610c85346956346ef7200f7a095a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DebugServer implements Closeable { | |
private final Map<Number, BiConsumer<ByteBuffer, SocketAddress>> handlers = new HashMap<>(); | |
private final ExecutorService executor = newSingleThreadExecutor(); | |
private final DatagramChannel channel; | |
private final ByteBuffer in; | |
private final ByteBuffer out; | |
public DebugServer(Number port, Number length) throws IOException { | |
this(port, length, ByteBuffer::get); | |
} | |
public DebugServer(Number port, Number length, Function<ByteBuffer, Number> opcodes) throws IOException { | |
in = allocate(length.intValue()); | |
out = allocate(length.intValue()); | |
in.clear(); | |
channel = open(); | |
channel.configureBlocking(true); | |
channel.bind(new InetSocketAddress("localhost", port.intValue())); | |
executor.submit(() -> { | |
while (channel.isOpen()) { | |
SocketAddress address = channel.receive(in); | |
in.flip(); | |
handlers.get(opcodes.apply(in)).accept(in, address); | |
in.clear(); | |
} | |
return null; | |
}); | |
} | |
public void send(SocketAddress address, Number opcode, Consumer<ByteBuffer> packet) { | |
try { | |
synchronized (out) { | |
out.clear(); | |
out.put(opcode.byteValue()); | |
packet.accept(out); | |
out.flip(); | |
channel.send(out, address); | |
} | |
} catch (IOException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
public void receive(Number opcode, BiConsumer<ByteBuffer, SocketAddress> handler) { | |
handlers.put(opcode, handler); | |
} | |
public void respond(Number opcode, Function<ByteBuffer, Consumer<ByteBuffer>> handler) { | |
respond(opcode, (request, address) -> handler.apply(request)); | |
} | |
public void respond(Number opcode, BiFunction<ByteBuffer, SocketAddress, Consumer<ByteBuffer>> handler) { | |
receive(opcode, (request, address) -> { | |
Consumer<ByteBuffer> response = handler.apply(request, address); | |
send(address, opcode, response); | |
}); | |
} | |
@Override | |
public void close() throws IOException { | |
channel.close(); | |
executor.shutdown(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment