Socket Reaper is a fairly simple tool that allows you to open a socket to a TCP-Socket and send a requests to it.
When the Request is being sent, you have the ability to wait for a response or just ignore the result.
It is designed to be used as a communication tool between two applications which need to communicate in real-time.
For help join my Discord server or contact me privately on Discord (@redreaperlp)
repositories {
maven("https://eldonexus.de/repository/maven-public/")
}
dependencies {
implementation("com.github.redreaperlp", "socket-reaper", "version")
}<project>
...
<repositories>
<repository>
<id>eldonexus</id>
<url>https://eldonexus.de/repository/maven-public/</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.redreaperlp</groupId>
<artifactId>socketapi</artifactId>
<version>1.0</version>
</dependency>
</project>- The server is initialized with a port on which it will listen for incoming connections
SocketServer server = new SocketServer(port);- The client is initialized with a host and a port to which it will connect
SocketClient client = new SocketClient(host, port);- This is the request that is expecting a response
- It has to extend the RequestPromising abstract class
public class RequestPing extends RequestPromising {
public static final String name = "ping"; // The name of the request (used for identification so it should be unique)
public RequestPing(long id) { // The id is used to identify the request when the response is received
super(id);
}
@Override
public String getName() { // Returns the name of the request
return name;
}
}- This is basically the same but with a slight change
- It has to extend the RequestVoiding abstract class
- The id is not needed as there is no response expected
public class RequestPing extends RequestVoiding {
public static final String name = "notification"; // The name of the request (used for identification so it should be unique)
public RequestPing() {
super();
}
@Override
public String getName() { // Returns the name of the request
return name;
}
}- The registration has to be done in both the client and the server like in the example below
- RequestPing.name refers to the name of the request RequestPing
- RequestPing.class refers to the class of the request RequestPing
public static void main(String[] args) {
RequestManager.registerRequest(RequestPing.name, RequestPing.class);
RequestManager.registerRequest(RequestRegister.name, RequestRegister.class);
}- The handler handling the request has to be registered. This can be done in both the client and the server like in the
example below
- SocketServer and SocketClient both extend the NetInstance class
- Encrypted communication is also possible, you can use
the useEncryption() method to specify a key
- Note: The key has to be the same for the server and the client, the best way is to manually set it in the configuration of your application
public static void main(String[] args) {
SocketServer server = new SocketServer(port);
//or
SocketClient client = new SocketClient(host, port);
//optionally you can specify an encryption key
server.useEncryption("key");
client.useEncryption("key");
//here we register the handler for the request
server.registerPromisingHandler(RequestPing.class, (req, data) -> {
//here you can handle the request, the data is the data that was sent with the request
//the req is the request itself (here RequestPing so you can access all fields and methods of the request)
});
//for servers, these handlers are applied to all clients,
//if you want to handle a request for a specific type of client, you have to create a new Custom Connection class
}- instead of creating a handler, you can also override
the validateResponse() method in
the RequestPromising
class
- this method is called when a response is received and the request is a RequestPromising
- if the response is not satisfying, you can call
the failed(int)
method to mark the request as failed
- You can send a request from both the client and the server.
- Here we take the Initialization of the server as an example
public static void main(String[] args) {
// Server or client is initialized beforehand (...)
// Request is retrieved, an ID is automatically generated if it's a response request
Request req = client.getRequest(RequestRegister.class);
// Data of the request is set, which is used in the RequestHandler
req.setData(new JSONObject().put("name", "test"));
// Two options: send the request and wait for the response or send the request and ignore the response
// If waiting for the response:
Response res = req.complete(); // This sends the request, waits for the response, or marks it as failed if it times out
if (req.failed()) {
// Handle the failure here
} else {
// Handle the response here
}
// If ignoring the response:
req.queue(); // This sends the request and ignores the response
}- if you have any fields in your request, you have to overwrite the pack() like in the example below to send the request with the data this is also the data that is received in the RequestHandler
public class RequestPlayerMoved extends RequestPromising {
private Player player;
private int x;
private int y;
public RequestPlayerMoved(long id, Player player, int x, int y) {
super(id);
this.player = player;
this.x = x;
this.y = y;
}
@Override
public void pack() {
setData(new JSONObject()
.put("player", player.toJson())
.put("x", x)
.put("y", y)
);
}
}- These are used to have connections with different handlers, for instance, you have a Minecraft Server with Proxy and
Games, on the Proxy you want to handle each game differently
- Normally you would have to write a complex logic to determine which game is sending the request and then handle it accordingly, this is where Custom Connection classes come into play
- You can create a Custom Connection class by extending the Connection class
public class GameConnection extends Connection {
public GameConnection(Socket socket, SocketServer server) {
super(socket, server);
}
@Override
public void registerHandlers() { // Here you can register the handlers for the specific connection and requests
getRequestHandler().registerPromisingHandler(RequestPlayerMoved.class, (req, data) -> {
//handle the request
});
}
}- You can register a Custom Connection class by calling the registerCustomConnection() method
- The first parameter is the name of the connection, the second parameter is the class of the connection
- Note: If you have registered at least one Custom Connection class, you have to specify one of your created classes, otherwise the server will reject the connection client.setConnectionIdentifier(String name)
public void start() {
ConnectionHandler h = ConnectionHandler.getInstance(); //This is singleton so you can call it from anywhere
h.registerCustomConnection("name", GameConnection.class);
}- Use a secure connection (Custom)
This project is licensed under the Apache License 2.0 - see the LICENSE file for details