Added no2all server code

This commit is contained in:
Willem Cazander 2024-11-29 13:29:03 +01:00
parent cd0e156b00
commit d38612ccda
97 changed files with 3459 additions and 0 deletions

View file

@ -0,0 +1,32 @@
package love.distributedrebirth.no2all.react.nostr.client;
import java.io.IOException;
import java.io.StringReader;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import love.distributedrebirth.no2all.nostr.model.NoStrRelayInfo;
import java.net.http.HttpResponse.BodyHandlers;
import jakarta.json.Json;
import jakarta.json.JsonReader;
public class NoStrRelayFetchInfo {
public NoStrRelayInfo fetchRelayInfo(URI uri) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder(uri).header("Accept", "application/nostr+json").build();
HttpResponse<String> response = HttpClient.newHttpClient().send(request, BodyHandlers.ofString());
if (response.statusCode() != 200) {
return null;
}
String contentJson = response.body();
try (JsonReader read = Json.createReader(new StringReader(contentJson))) {
NoStrRelayInfo result = new NoStrRelayInfo(read.readObject());
return result;
}
}
}

View file

@ -0,0 +1,9 @@
package love.distributedrebirth.no2all.react.nostr.client;
public enum NoStrRelayReadType {
NONE,
ALL,
;
}

View file

@ -0,0 +1,71 @@
package love.distributedrebirth.no2all.react.nostr.client;
import love.distributedrebirth.no2all.nostr.NoStr;
import love.distributedrebirth.no2all.nostr.fire.NoStrFirePipe;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelay;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientAuth;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientCount;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientEose;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientEvent;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientNotice;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientOk;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayAuth;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayClose;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayCount;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayEvent;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayReq;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import love.distributedrebirth.no2all.react.No2AllReact;
import love.distributedrebirth.no2all.react.No2AllReactListener;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
import love.distributedrebirth.no2all.react.wire.client.No2AllActClientClose;
import love.distributedrebirth.no2all.react.wire.client.No2AllActClientSendMessage;
import love.distributedrebirth.no2all.react.wire.client.No2AllArtClient;
import love.distributedrebirth.no2all.react.wire.client.No2AllArtClientOnMessage;
import love.distributedrebirth.no2all.react.wire.client.No2AllRtsClient;
public class NoStrRtsClient implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(NoStrRtsClient.class);
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
No2AllReact react = signal.getReact();
react.claim(API);
react.registrate(No2AllRtsClient.API, No2AllArtClient.class, artClient -> {
No2AllReactSlot clientSlot = artClient.getData().getSlot();
react.claimIn(clientSlot, NoStrMsgToRelayAuth.class);
react.claimIn(clientSlot, NoStrMsgToRelayClose.class);
react.claimIn(clientSlot, NoStrMsgToRelayCount.class);
react.claimIn(clientSlot, NoStrMsgToRelayEvent.class);
react.claimIn(clientSlot, NoStrMsgToRelayReq.class);
react.claimOut(clientSlot, NoStrMsgToClientAuth.class);
react.claimOut(clientSlot, NoStrMsgToClientCount.class);
react.claimOut(clientSlot, NoStrMsgToClientEose.class);
react.claimOut(clientSlot, NoStrMsgToClientEvent.class);
react.claimOut(clientSlot, NoStrMsgToClientNotice.class);
react.claimOut(clientSlot, NoStrMsgToClientOk.class);
NoStrFirePipe pipeReader = NoStr.FACTORY.pipeReaderClient(reason -> {
react.fire(clientSlot, No2AllActClientClose.ofRefuse(reason));
}, message -> {
react.fire(clientSlot, message);
});
react.registrate(clientSlot, No2AllArtClientOnMessage.class, v -> {
pipeReader.onFire(v.getData().getMessage());
});
react.registrate(clientSlot, NoStrMsgToRelayAuth.class, pipeWriter(react, clientSlot));
react.registrate(clientSlot, NoStrMsgToRelayClose.class, pipeWriter(react, clientSlot));
react.registrate(clientSlot, NoStrMsgToRelayCount.class, pipeWriter(react, clientSlot));
react.registrate(clientSlot, NoStrMsgToRelayEvent.class, pipeWriter(react, clientSlot));
react.registrate(clientSlot, NoStrMsgToRelayReq.class, pipeWriter(react, clientSlot));
});
}
private <T extends NoStrMsgToRelay> No2AllReactListener<T> pipeWriter(No2AllReact react, No2AllReactSlot clientSlot) {
return v -> {
react.fire(clientSlot, new No2AllActClientSendMessage(v.getData().toBible().toString()));
};
}
}

View file

@ -0,0 +1,86 @@
package love.distributedrebirth.no2all.react.nostr.server;
import love.distributedrebirth.no2all.nostr.NoStr;
import love.distributedrebirth.no2all.nostr.fire.NoStrFirePipe;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClient;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientAuth;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientCount;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientEose;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientEvent;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientNotice;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientOk;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayAuth;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayClose;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayCount;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayEvent;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayReq;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import love.distributedrebirth.no2all.react.No2AllReact;
import love.distributedrebirth.no2all.react.No2AllReactListener;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
import love.distributedrebirth.no2all.react.wire.server.No2AllActServerBroadcastMessage;
import love.distributedrebirth.no2all.react.wire.server.No2AllActServerSocketClose;
import love.distributedrebirth.no2all.react.wire.server.No2AllActServerSocketSendMessage;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServer;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServerSocket;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServerSocketOnMessage;
import love.distributedrebirth.no2all.react.wire.server.No2AllRtsServer;
public class NoStrRtsServer implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(NoStrRtsServer.class);
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
No2AllReact react = signal.getReact();
react.claim(API);
react.requireSlot(API, No2AllRtsServer.API);
react.claimIn(API, NoStrMsgToClientNotice.class);
react.registrate(API, NoStrMsgToClientNotice.class, v -> {
react.fireForEach(No2AllRtsServer.API, new No2AllActServerBroadcastMessage(v.getData().toBible().toString()));
});
react.registrate(No2AllRtsServer.API, No2AllArtServer.class, artServer -> {
No2AllReactSlot serverSlot = artServer.getData().getSlot();
react.claimIn(serverSlot, NoStrMsgToClientNotice.class);
react.registrate(serverSlot, No2AllArtServerSocket.class, artSocket -> {
No2AllReactSlot socketSlot = artSocket.getData().getSlot();
react.claimIn(socketSlot, NoStrMsgToClientAuth.class);
react.claimIn(socketSlot, NoStrMsgToClientCount.class);
react.claimIn(socketSlot, NoStrMsgToClientEose.class);
react.claimIn(socketSlot, NoStrMsgToClientEvent.class);
react.claimIn(socketSlot, NoStrMsgToClientNotice.class);
react.claimIn(socketSlot, NoStrMsgToClientOk.class);
react.claimOut(socketSlot, NoStrMsgToRelayAuth.class);
react.claimOut(socketSlot, NoStrMsgToRelayClose.class);
react.claimOut(socketSlot, NoStrMsgToRelayCount.class);
react.claimOut(socketSlot, NoStrMsgToRelayEvent.class);
react.claimOut(socketSlot, NoStrMsgToRelayReq.class);
NoStrFirePipe pipeReader = NoStr.FACTORY.pipeReaderRelay(reason -> {
react.fire(socketSlot, No2AllActServerSocketClose.ofRefuse(reason));
}, message -> {
react.fire(socketSlot, message);
});
react.registrate(socketSlot, No2AllArtServerSocketOnMessage.class, v -> {
pipeReader.onFire(v.getData().getMessage());
});
react.registrate(socketSlot, NoStrMsgToClientAuth.class, pipeWriter(react, socketSlot));
react.registrate(socketSlot, NoStrMsgToClientCount.class, pipeWriter(react, socketSlot));
react.registrate(socketSlot, NoStrMsgToClientEose.class, pipeWriter(react, socketSlot));
react.registrate(socketSlot, NoStrMsgToClientEvent.class, pipeWriter(react, socketSlot));
react.registrate(socketSlot, NoStrMsgToClientNotice.class, pipeWriter(react, socketSlot));
react.registrate(socketSlot, NoStrMsgToClientOk.class, pipeWriter(react, socketSlot));
});
react.registrate(serverSlot, NoStrMsgToClientNotice.class, v -> {
react.fire(serverSlot, new No2AllActServerBroadcastMessage(v.getData().toBible().toString()));
});
});
}
private <T extends NoStrMsgToClient> No2AllReactListener<T> pipeWriter(No2AllReact react, No2AllReactSlot clientSlot) {
return v -> {
react.fire(clientSlot, new No2AllActServerSocketSendMessage(v.getData().toBible().toString()));
};
}
}

View file

@ -0,0 +1,22 @@
package love.distributedrebirth.no2all.react.nostr.server.relay;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEvent;
public final class NoStrArtServerRelayStoreEvent {
private final NoStrEvent event;
private final String remoteAddr;
protected NoStrArtServerRelayStoreEvent(NoStrEvent event, String remoteAddr) {
this.event = event;
this.remoteAddr = remoteAddr;
}
public NoStrEvent getEvent() {
return event;
}
public String getRemoteAddr() {
return remoteAddr;
}
}

View file

@ -0,0 +1,65 @@
package love.distributedrebirth.no2all.react.nostr.server.relay;
import java.util.logging.Logger;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEvent;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEventSignature;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToClientOk;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayEvent;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplMessageOkReason;
import love.distributedrebirth.no2all.react.No2AllReact;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
import love.distributedrebirth.no2all.react.nostr.server.NoStrRtsServer;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServer;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServerSocket;
import love.distributedrebirth.no2all.react.wire.server.No2AllRtsServer;
public class NoStrRtsServerRelay implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(NoStrRtsServerRelay.class);
private static final Logger logger = Logger.getLogger(NoStrRtsServerRelay.class.getName());
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
No2AllReact react = signal.getReact();
react.claim(API);
react.claimOut(API, NoStrArtServerRelayStoreEvent.class);
react.requireSlot(API, NoStrRtsServer.API);
react.registrate(No2AllRtsServer.API, No2AllArtServer.class, artServer -> {
No2AllReactSlot serverSlot = artServer.getData().getSlot();
react.registrate(serverSlot, No2AllArtServerSocket.class, artSocket -> {
No2AllReactSlot socketSlot = artSocket.getData().getSlot();
react.registrate(socketSlot, NoStrMsgToRelayEvent.class, v -> {
handleRelayEvent(react, v.getData().getEvent(), artSocket.getData().getRemoteAddr(), socketSlot);
});
});
});
}
private void handleRelayEvent(No2AllReact react, NoStrEvent event, String remoteAddr, No2AllReactSlot socketSlot) {
boolean eventSaved = false;
String eventResponse = "";
NoStrImplMessageOkReason eventReason = NoStrImplMessageOkReason.DEFAULT;
// filter on
event.getPayload().getKind();
event.getPayload().getPublicKey();
event.getPayload().getTags();
eventSaved = NoStrEventSignature.verify(event);
if (!eventSaved) {
eventReason = NoStrImplMessageOkReason.INVALID;
}
logger.fine("Validate event: " + eventSaved + " eventId: " + event.getId());
if (eventSaved) {
react.fire(API, new NoStrArtServerRelayStoreEvent(event, remoteAddr));
}
react.fire(socketSlot, new NoStrMsgToClientOk(event.getId(), eventSaved, eventReason, eventResponse));
}
}

View file

@ -0,0 +1,39 @@
package love.distributedrebirth.no2all.react.nostr.server.relay;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayClose;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayReq;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import love.distributedrebirth.no2all.react.No2AllReact;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServer;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServerSocket;
import love.distributedrebirth.no2all.react.wire.server.No2AllRtsServer;
public class NoStrRtsServerRelaySubs implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(NoStrRtsServerRelaySubs.class);
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
No2AllReact react = signal.getReact();
react.claim(API);
react.requireSlot(API, NoStrRtsServerRelay.API);
react.registrate(No2AllRtsServer.API, No2AllArtServer.class, v -> {
No2AllReactSlot serverSlot = v.getData().getSlot();
react.registrate(serverSlot, No2AllArtServerSocket.class, x -> {
No2AllReactSlot socketSlot = x.getData().getSlot();
react.registrate(socketSlot, NoStrMsgToRelayReq.class, y -> {
String subId = y.getData().getSubscriptionId();
y.getData().getFilters();
System.out.println("sub new: " + subId);
});
react.registrate(socketSlot, NoStrMsgToRelayClose.class, y -> {
String subId = y.getData().getSubscriptionId();
System.out.println("sub clone: " + subId);
});
});
});
}
}

View file

@ -0,0 +1,104 @@
package love.distributedrebirth.no2all.react.nostr.client;
import java.net.URI;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import love.distributedrebirth.no2all.nostr.NoStr;
import love.distributedrebirth.no2all.nostr.fire.NoStrFireWaterBoiler;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentity;
import love.distributedrebirth.no2all.nostr.model.NoStrIdentityPrivateKey;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEvent;
import love.distributedrebirth.no2all.nostr.model.message.NoStrMsgToRelayEvent;
import love.distributedrebirth.no2all.nostr.nip.NoStrImplEventKind;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.warp.No2AllReactWarpCore;
import love.distributedrebirth.no2all.react.warp.No2AllRtsWarpSpeedMonitor;
import love.distributedrebirth.no2all.react.wire.client.No2AllActClient;
import love.distributedrebirth.no2all.react.wire.client.No2AllActClientClose;
import love.distributedrebirth.no2all.react.wire.client.No2AllActClientConnect;
import love.distributedrebirth.no2all.react.wire.client.No2AllArtClient;
import love.distributedrebirth.no2all.react.wire.client.No2AllArtClientOnClose;
import love.distributedrebirth.no2all.react.wire.client.No2AllArtClientOnError;
import love.distributedrebirth.no2all.react.wire.client.No2AllArtClientOnMessage;
import love.distributedrebirth.no2all.react.wire.client.No2AllArtClientOnOpen;
import love.distributedrebirth.no2all.react.wire.client.No2AllArtClientOnStart;
import love.distributedrebirth.no2all.react.wire.client.No2AllRtsClient;
import love.distributedrebirth.no2all.wire.ojw.OjwWireClientEndpoint;
public class NoStrClientTest {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newFixedThreadPool(10);
NoStrIdentity nid = new NoStrIdentity(NoStrIdentityPrivateKey.ofRandom());
No2AllReactWarpCore react = new No2AllReactWarpCore();
react.load(new No2AllRtsWarpSpeedMonitor());
react.load(new No2AllRtsClient());
react.load(new NoStrRtsClient());
react.registrate(No2AllRtsClient.API, No2AllArtClient.class, v -> {
No2AllReactSlot clientSlot = v.getData().getSlot();
System.out.println("NoStrClient created: " + clientSlot.getSlotPath());
react.registrate(clientSlot, No2AllArtClientOnError.class, x -> {
System.out.println("NoStrClient socket error: " + x.getData().getError().getMessage());
});
react.registrate(clientSlot, No2AllArtClientOnClose.class, x -> {
System.out.println("NoStrClient socket close: " + x.getData().getCode() + " " + x.getData().getReason());
});
react.registrate(clientSlot, No2AllArtClientOnOpen.class, x -> {
System.out.println("NoStrClient socket open");
executor.submit(() -> {
try {
for (int i = 0; i < 10; i++) {
NoStrFireWaterBoiler userBoiler = NoStr.FACTORY.boiler(nid);
NoStrEvent event = userBoiler.smoker()
.tagSubject("Reply to all")
.tagR("")
.burn()
.water(NoStrImplEventKind.TEXT_NOTE, "Hello world:"+i);
System.out.println("send msg");
NoStrMsgToRelayEvent msg = new NoStrMsgToRelayEvent(event);
react.fire(clientSlot, msg);
Thread.sleep(1000);
}
} catch (Exception ex) {
ex.printStackTrace();
}
});
});
react.registrate(clientSlot, No2AllArtClientOnMessage.class, y -> {
System.out.println("NoStrClient got msg1: " + y.getData().getMessage());
});
// Todo "OnStart" is not working...
react.registrate(clientSlot, No2AllArtClientOnStart.class, x -> {
System.out.println("NoStrClient socket start");
});
react.fire(clientSlot, new No2AllActClientConnect());
});
OjwWireClientEndpoint clientEndpoint = new OjwWireClientEndpoint(new URI("ws://localhost:8080/event"));
System.out.println("NoStrClient start");
react.fire(No2AllRtsClient.API, new No2AllActClient(clientEndpoint));
Thread.sleep(30000);
executor.shutdown();
executor.awaitTermination(60, TimeUnit.SECONDS);
Thread exitTimer = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
System.out.println("NoStrClient stopping");
react.fireForEach(No2AllRtsClient.API, No2AllActClientClose.ofNormal("exit"));
System.out.println("NoStrClient stopped");
});
exitTimer.start();
}
}

View file

@ -0,0 +1,65 @@
package love.distributedrebirth.no2all.react.nostr.server;
import java.net.InetSocketAddress;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.nostr.server.relay.NoStrRtsServerRelay;
import love.distributedrebirth.no2all.react.nostr.server.relay.NoStrRtsServerRelaySubs;
import love.distributedrebirth.no2all.react.warp.No2AllReactWarpCore;
import love.distributedrebirth.no2all.react.warp.No2AllRtsWarpSpeedMonitor;
import love.distributedrebirth.no2all.react.wire.server.No2AllActServer;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServer;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServerOnStart;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServerSocket;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServerSocketOnClose;
import love.distributedrebirth.no2all.react.wire.server.No2AllRtsServerLog;
import love.distributedrebirth.no2all.react.wire.server.No2AllRtsServer;
import love.distributedrebirth.no2all.wire.ojw.OjwWireServer;
import love.distributedrebirth.no2all.wire.ojw.OjwWireServerEndpoint;
public class NoStrServerTest {
static OjwWireServer server = null;
public static void main(String[] args) throws Exception {
No2AllReactWarpCore react = new No2AllReactWarpCore();
react.load(new No2AllRtsWarpSpeedMonitor());
react.load(new No2AllRtsServer());
react.load(new No2AllRtsServerLog());
react.load(new NoStrRtsServer());
react.load(new NoStrRtsServerRelay());
react.load(new NoStrRtsServerRelaySubs());
react.registrate(No2AllRtsServer.API, No2AllArtServer.class, artServer -> {
No2AllReactSlot serverSlot = artServer.getData().getSlot();
react.registrate(serverSlot, No2AllArtServerOnStart.class, v -> {
System.out.println("RelayServer started: " + v.getTarget().getSlotSlug());
});
react.registrate(serverSlot, No2AllArtServerSocket.class, v -> {
System.out.println("RelayServer client-open: " + v.getData().getSlot().getSlotPath());
react.registrate(v.getData().getSlot(), No2AllArtServerSocketOnClose.class, y -> {
System.out.println("RelayServer client-close: " + y.getData().getCode() + " of: " + y.getTarget().getSlotPath());
});
});
react.registrate(serverSlot, OjwWireServer.class, x -> { // TODO: add interface matching ...
server = x.getData();
});
});
System.out.println("RelayServer fire configs");
OjwWireServerEndpoint serverEndpoint = new OjwWireServerEndpoint(new InetSocketAddress(8080), 120);
react.fire(No2AllRtsServer.API, new No2AllActServer(serverEndpoint));
for (int i=0;i<1000;i++) {
//react.fire(No2AllServerRTS.API, react);
Thread.sleep(100);
}
Thread.sleep(40000);
if (server != null) {
System.out.println("RelayServers stopping");
server.getHandler().stop();
}
//react.fireForEach(No2AllServerRTS.API, new No2AllActServerStop());
System.out.println("RelayServers stopped");
}
}

View file

@ -0,0 +1,16 @@
package love.distributedrebirth.no2all.react.wire.client;
import love.distributedrebirth.no2all.wire.WireClientEndpoint;
public final class No2AllActClient {
private final WireClientEndpoint endpoint;
public No2AllActClient(WireClientEndpoint endpoint) {
this.endpoint = endpoint;
}
public WireClientEndpoint getEndpoint() {
return endpoint;
}
}

View file

@ -0,0 +1,28 @@
package love.distributedrebirth.no2all.react.wire.client;
public final class No2AllActClientClose {
private final int code;
private final String message;
public No2AllActClientClose(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public static No2AllActClientClose ofNormal(String message) {
return new No2AllActClientClose(1000, message);
}
public static No2AllActClientClose ofRefuse(String message) {
return new No2AllActClientClose(1003, message);
}
}

View file

@ -0,0 +1,7 @@
package love.distributedrebirth.no2all.react.wire.client;
public final class No2AllActClientConnect {
public No2AllActClientConnect() {
}
}

View file

@ -0,0 +1,16 @@
package love.distributedrebirth.no2all.react.wire.client;
import java.nio.ByteBuffer;
public final class No2AllActClientSendBinary {
private final ByteBuffer message;
public No2AllActClientSendBinary(ByteBuffer message) {
this.message = message;
}
public ByteBuffer getMessage() {
return message;
}
}

View file

@ -0,0 +1,14 @@
package love.distributedrebirth.no2all.react.wire.client;
public final class No2AllActClientSendMessage {
private final String message;
public No2AllActClientSendMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}

View file

@ -0,0 +1,11 @@
package love.distributedrebirth.no2all.react.wire.client;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.warp.No2AllActAbstractSlot;
public final class No2AllArtClient extends No2AllActAbstractSlot {
protected No2AllArtClient(No2AllReactSlot slot) {
super(slot);
}
}

View file

@ -0,0 +1,16 @@
package love.distributedrebirth.no2all.react.wire.client;
import java.nio.ByteBuffer;
public final class No2AllArtClientOnBinary {
private final ByteBuffer message;
protected No2AllArtClientOnBinary(ByteBuffer message) {
this.message = message;
}
public ByteBuffer getMessage() {
return message;
}
}

View file

@ -0,0 +1,26 @@
package love.distributedrebirth.no2all.react.wire.client;
public final class No2AllArtClientOnClose {
private final int code;
private final String reason;
private final boolean remote;
protected No2AllArtClientOnClose(int code, String reason, boolean remote) {
this.code = code;
this.reason = reason;
this.remote = remote;
}
public int getCode() {
return code;
}
public String getReason() {
return reason;
}
public boolean isRemote() {
return remote;
}
}

View file

@ -0,0 +1,14 @@
package love.distributedrebirth.no2all.react.wire.client;
public final class No2AllArtClientOnError {
private final Throwable error;
protected No2AllArtClientOnError(Throwable error) {
this.error = error;
}
public Throwable getError() {
return error;
}
}

View file

@ -0,0 +1,14 @@
package love.distributedrebirth.no2all.react.wire.client;
public final class No2AllArtClientOnMessage {
private final String message;
protected No2AllArtClientOnMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}

View file

@ -0,0 +1,7 @@
package love.distributedrebirth.no2all.react.wire.client;
public final class No2AllArtClientOnOpen {
protected No2AllArtClientOnOpen() {
}
}

View file

@ -0,0 +1,11 @@
package love.distributedrebirth.no2all.react.wire.client;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.warp.No2AllActAbstractSlot;
public final class No2AllArtClientOnStart extends No2AllActAbstractSlot {
protected No2AllArtClientOnStart(No2AllReactSlot slot) {
super(slot);
}
}

View file

@ -0,0 +1,90 @@
package love.distributedrebirth.no2all.react.wire.client;
import java.nio.ByteBuffer;
import love.distributedrebirth.no2all.react.No2AllReact;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
import love.distributedrebirth.no2all.wire.WireClient;
import love.distributedrebirth.no2all.wire.WireClientEndpoint;
import love.distributedrebirth.no2all.wire.WireClientHandler;
public class No2AllRtsClient implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(No2AllRtsClient.class);
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
No2AllReact react = signal.getReact();
react.claim(API);
react.claimIn(API, No2AllActClient.class);
react.claimOut(API, No2AllArtClient.class);
react.registrate(API, No2AllActClient.class, actClient -> {
WireClientEndpoint clientEndpoint = actClient.getData().getEndpoint();
No2AllReactSlot clientSlot = No2AllReactSlot.of(API, "wireId=" + clientEndpoint.wireId());
WireClient client = clientEndpoint.wireClient(wireHandler(react, clientSlot));
react.claim(clientSlot);
react.claimIn(clientSlot, No2AllActClientConnect.class);
react.claimIn(clientSlot, No2AllActClientClose.class);
react.claimIn(clientSlot, No2AllActClientSendMessage.class);
react.claimIn(clientSlot, No2AllActClientSendBinary.class);
react.claimOut(clientSlot, No2AllArtClientOnStart.class);
react.claimOut(clientSlot, No2AllArtClientOnOpen.class);
react.claimOut(clientSlot, No2AllArtClientOnClose.class);
react.claimOut(clientSlot, No2AllArtClientOnError.class);
react.claimOut(clientSlot, No2AllArtClientOnMessage.class);
react.claimOut(clientSlot, No2AllArtClientOnBinary.class);
react.claimOut(clientSlot, WireClient.class);
react.registrate(clientSlot, No2AllActClientConnect.class, v -> {
client.connect();
});
react.registrate(clientSlot, No2AllActClientClose.class, v -> {
client.close(v.getData().getCode(), v.getData().getMessage());
});
react.registrate(clientSlot, No2AllActClientSendMessage.class, v -> {
client.sendMessage(v.getData().getMessage());
});
react.registrate(clientSlot, No2AllActClientSendBinary.class, v -> {
client.sendBinary(v.getData().getMessage());
});
react.fire(API, new No2AllArtClient(clientSlot));
react.fire(clientSlot, client);
});
}
private WireClientHandler wireHandler(No2AllReact react, No2AllReactSlot clientSlot) {
return new WireClientHandler() {
@Override
public void onStart() {
react.fire(clientSlot, new No2AllArtClientOnStart(clientSlot));
}
@Override
public void onOpen() {
react.fire(clientSlot, new No2AllArtClientOnOpen());
}
@Override
public void onClose(int code, String reason, boolean remote) {
react.fire(clientSlot, new No2AllArtClientOnClose(code, reason, remote));
}
@Override
public void onError(Throwable error) {
react.fire(clientSlot, new No2AllArtClientOnError(error));
}
@Override
public void onMessage(String message) {
react.fire(clientSlot, new No2AllArtClientOnMessage(message));
}
@Override
public void onBinary(ByteBuffer message) {
react.fire(clientSlot, new No2AllArtClientOnBinary(message));
}
};
}
}

View file

@ -0,0 +1,16 @@
package love.distributedrebirth.no2all.react.wire.server;
import love.distributedrebirth.no2all.wire.WireServerEndpoint;
public final class No2AllActServer {
private final WireServerEndpoint endpoint;
public No2AllActServer(WireServerEndpoint endpoint) {
this.endpoint = endpoint;
}
public WireServerEndpoint getEndpoint() {
return endpoint;
}
}

View file

@ -0,0 +1,16 @@
package love.distributedrebirth.no2all.react.wire.server;
import java.nio.ByteBuffer;
public final class No2AllActServerBroadcastBinary {
private final ByteBuffer message;
public No2AllActServerBroadcastBinary(ByteBuffer message) {
this.message = message;
}
public ByteBuffer getMessage() {
return message;
}
}

View file

@ -0,0 +1,14 @@
package love.distributedrebirth.no2all.react.wire.server;
public final class No2AllActServerBroadcastMessage {
private final String message;
public No2AllActServerBroadcastMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}

View file

@ -0,0 +1,28 @@
package love.distributedrebirth.no2all.react.wire.server;
public final class No2AllActServerSocketClose {
private final int code;
private final String messag;
public No2AllActServerSocketClose(int code, String message) {
this.code = code;
this.messag = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return messag;
}
public static No2AllActServerSocketClose ofNormal(String message) {
return new No2AllActServerSocketClose(1000, message);
}
public static No2AllActServerSocketClose ofRefuse(String message) {
return new No2AllActServerSocketClose(1003, message);
}
}

View file

@ -0,0 +1,16 @@
package love.distributedrebirth.no2all.react.wire.server;
import java.nio.ByteBuffer;
public final class No2AllActServerSocketSendBinary {
private final ByteBuffer message;
public No2AllActServerSocketSendBinary(ByteBuffer message) {
this.message = message;
}
public ByteBuffer getMessage() {
return message;
}
}

View file

@ -0,0 +1,14 @@
package love.distributedrebirth.no2all.react.wire.server;
public final class No2AllActServerSocketSendMessage {
private final String message;
public No2AllActServerSocketSendMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}

View file

@ -0,0 +1,11 @@
package love.distributedrebirth.no2all.react.wire.server;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.warp.No2AllActAbstractSlot;
public final class No2AllArtServer extends No2AllActAbstractSlot {
protected No2AllArtServer(No2AllReactSlot slot) {
super(slot);
}
}

View file

@ -0,0 +1,14 @@
package love.distributedrebirth.no2all.react.wire.server;
public final class No2AllArtServerOnError {
private final Throwable error;
protected No2AllArtServerOnError(Throwable error) {
this.error = error;
}
public Throwable getError() {
return error;
}
}

View file

@ -0,0 +1,7 @@
package love.distributedrebirth.no2all.react.wire.server;
public final class No2AllArtServerOnStart {
protected No2AllArtServerOnStart() {
}
}

View file

@ -0,0 +1,18 @@
package love.distributedrebirth.no2all.react.wire.server;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.warp.No2AllActAbstractSlot;
public final class No2AllArtServerSocket extends No2AllActAbstractSlot {
private final String remoteAddr;
protected No2AllArtServerSocket(No2AllReactSlot slot, String remoteAddr) {
super(slot);
this.remoteAddr = remoteAddr;
}
public String getRemoteAddr() {
return remoteAddr;
}
}

View file

@ -0,0 +1,16 @@
package love.distributedrebirth.no2all.react.wire.server;
import java.nio.ByteBuffer;
public final class No2AllArtServerSocketOnBinary {
private final ByteBuffer message;
protected No2AllArtServerSocketOnBinary(ByteBuffer message) {
this.message = message;
}
public ByteBuffer getMessage() {
return message;
}
}

View file

@ -0,0 +1,26 @@
package love.distributedrebirth.no2all.react.wire.server;
public final class No2AllArtServerSocketOnClose {
private final int code;
private final String reason;
private final boolean remote;
protected No2AllArtServerSocketOnClose(int code, String reason, boolean remote) {
this.code = code;
this.reason = reason;
this.remote = remote;
}
public int getCode() {
return code;
}
public String getReason() {
return reason;
}
public boolean isRemote() {
return remote;
}
}

View file

@ -0,0 +1,14 @@
package love.distributedrebirth.no2all.react.wire.server;
public final class No2AllArtServerSocketOnError {
private final Throwable error;
protected No2AllArtServerSocketOnError(Throwable error) {
this.error = error;
}
public Throwable getError() {
return error;
}
}

View file

@ -0,0 +1,14 @@
package love.distributedrebirth.no2all.react.wire.server;
public final class No2AllArtServerSocketOnMessage {
private final String message;
protected No2AllArtServerSocketOnMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}

View file

@ -0,0 +1,108 @@
package love.distributedrebirth.no2all.react.wire.server;
import java.nio.ByteBuffer;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import love.distributedrebirth.no2all.react.No2AllReact;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
import love.distributedrebirth.no2all.wire.WireServer;
import love.distributedrebirth.no2all.wire.WireServerEndpoint;
import love.distributedrebirth.no2all.wire.WireServerHandler;
import love.distributedrebirth.no2all.wire.WireServerSocket;
public class No2AllRtsServer implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(No2AllRtsServer.class);
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
No2AllReact react = signal.getReact();
react.claim(API);
react.claimIn(API, No2AllActServer.class);
react.claimOut(API, No2AllArtServer.class);
react.registrate(API, No2AllActServer.class, actServer -> {
WireServerEndpoint serverEndpoint = actServer.getData().getEndpoint();
No2AllReactSlot serverSlot = No2AllReactSlot.of(API, "wireId=" + serverEndpoint.wireId());
WireServer server = serverEndpoint.wireServer(wireHandler(react, serverSlot));
react.claim(serverSlot);
react.claimIn(serverSlot, No2AllActServerBroadcastMessage.class);
react.claimIn(serverSlot, No2AllActServerBroadcastBinary.class);
react.claimOut(serverSlot, No2AllArtServerOnStart.class);
react.claimOut(serverSlot, No2AllArtServerSocket.class);
react.claimOut(serverSlot, No2AllArtServerOnError.class);
react.claimOut(serverSlot, WireServer.class);
react.registrate(serverSlot, No2AllActServerBroadcastMessage.class, v -> {
server.broadcastMessage(v.getData().getMessage());
});
react.registrate(serverSlot, No2AllActServerBroadcastBinary.class, v -> {
server.broadcastBinary(v.getData().getMessage());
});
react.fire(API, new No2AllArtServer(serverSlot));
react.fire(serverSlot, server);
});
}
private WireServerHandler wireHandler(No2AllReact react, No2AllReactSlot serverSlot) {
return new WireServerHandler() {
private No2AllReactSlot socketSlug(WireServerSocket conn) {
return No2AllReactSlot.of(serverSlot, "hashCode=" + conn.hashCode());
}
@Override
public void onStart() {
react.fire(serverSlot, new No2AllArtServerOnStart());
}
@Override
public void onOpen(WireServerSocket conn) {
No2AllReactSlot socketSlot = socketSlug(conn);
react.claim(socketSlot);
react.claimIn(socketSlot, No2AllActServerSocketSendMessage.class);
react.claimIn(socketSlot, No2AllActServerSocketSendBinary.class);
react.claimIn(socketSlot, No2AllActServerSocketClose.class);
react.claimOut(socketSlot, No2AllArtServerSocketOnClose.class);
react.claimOut(socketSlot, No2AllArtServerSocketOnError.class);
react.claimOut(socketSlot, No2AllArtServerSocketOnMessage.class);
react.claimOut(socketSlot, No2AllArtServerSocketOnBinary.class);
react.registrate(socketSlot, No2AllActServerSocketSendMessage.class, v -> {
conn.sendMessage(v.getData().getMessage());
});
react.registrate(socketSlot, No2AllActServerSocketSendBinary.class, v -> {
conn.sendBinary(v.getData().getMessage());
});
react.registrate(socketSlot, No2AllActServerSocketClose.class, v -> {
conn.close(v.getData().getCode(), v.getData().getMessage());
});
react.fire(serverSlot, new No2AllArtServerSocket(socketSlot, conn.getRemoteAddress()));
}
@Override
public void onClose(WireServerSocket conn, int code, String reason, boolean remote) {
No2AllReactSlot socketSlot = socketSlug(conn);
react.fire(socketSlot, new No2AllArtServerSocketOnClose(code, reason, remote));
react.release(socketSlot);
}
@Override
public void onError(WireServerSocket conn, Throwable error) {
if (conn != null) {
react.fire(socketSlug(conn), new No2AllArtServerSocketOnError(error));
} else {
react.fire(serverSlot, new No2AllArtServerOnError(error));
}
}
@Override
public void onMessage(WireServerSocket conn, String message) {
react.fire(socketSlug(conn), new No2AllArtServerSocketOnMessage(message));
}
@Override
public void onBinary(WireServerSocket conn, ByteBuffer message) {
react.fire(socketSlug(conn), new No2AllArtServerSocketOnBinary(message));
}
};
}
}

View file

@ -0,0 +1,38 @@
package love.distributedrebirth.no2all.react.wire.server;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import java.util.logging.Logger;
import love.distributedrebirth.no2all.react.No2AllReact;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
public class No2AllRtsServerLog implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(No2AllRtsServerLog.class);
private static final Logger logger = Logger.getLogger(No2AllRtsServerLog.class.getName());
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
No2AllReact react = signal.getReact();
react.claim(API);
react.registrate(No2AllRtsServer.API, No2AllArtServer.class, artServer -> {
No2AllReactSlot serverSlot = artServer.getData().getSlot();
react.registrate(serverSlot, No2AllActServerBroadcastMessage.class, v -> {
logger.info("broadcastMessage: " + v.getData().getMessage());
});
react.registrate(serverSlot, No2AllArtServerSocket.class, v -> {
No2AllReactSlot socketSlot = v.getData().getSlot();
String wireId = socketSlot.getSlotSlug();
react.registrate(socketSlot, No2AllArtServerSocketOnMessage.class, z -> {
logger.info(wireId+".socketOnMessage: " + z.getData().getMessage());
});
react.registrate(socketSlot, No2AllActServerSocketSendMessage.class, z -> {
logger.info(wireId+".socketSendMessage: " + z.getData().getMessage());
});
});
});
}
}

View file

@ -0,0 +1,17 @@
package love.distributedrebirth.no2all.react;
public interface No2AllReact {
void claim(No2AllReactSlot slot);
void claimIn(No2AllReactSlot slot, Class<?> eventType);
void claimOut(No2AllReactSlot slot, Class<?> eventType);
void requireSlot(No2AllReactSlot slot, No2AllReactSlot dep);
void requireService(No2AllReactSlot slot, Class<?> serviceType);
void fire(No2AllReactSlot slot, Object event);
void fireForEach(No2AllReactSlot slot, Object event);
<T> void registrate(No2AllReactSlot slot, Class<T> eventType, No2AllReactListener<T> listener);
<T> T service(Class<T> serviceType);
void release(No2AllReactSlot slot);
}

View file

@ -0,0 +1,7 @@
package love.distributedrebirth.no2all.react;
@FunctionalInterface
public interface No2AllReactListener<T> {
void onEvent(No2AllReactSlotSignal<T> signal);
}

View file

@ -0,0 +1,75 @@
package love.distributedrebirth.no2all.react;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public final class No2AllReactSlot {
private final No2AllReactSlot parent;
private final String slotSlug;
private final String slotPath;
private No2AllReactSlot(No2AllReactSlot parent, String slotSlug) {
this.parent = parent;
this.slotSlug = slotSlug;
this.slotPath = createSlotPath();
}
public No2AllReactSlot getParent() {
return parent;
}
public String getSlotSlug() {
return slotSlug;
}
public String getSlotPath() {
return slotPath;
}
public String createSlotPath() {
List<String> slugs = new ArrayList<>();
No2AllReactSlot parentNode = this;
while (parentNode != null) {
slugs.add(parentNode.getSlotSlug());
parentNode = parentNode.getParent();
}
StringBuilder buf = new StringBuilder();
for (int i = slugs.size() - 1; i >= 0; i--) {
buf.append(slugs.get(i));
if (i > 0) {
buf.append(',');
}
}
return buf.toString();
}
@Override
public int hashCode() {
return Objects.hash(slotPath);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
No2AllReactSlot other = (No2AllReactSlot) obj;
return Objects.equals(slotPath, other.slotPath);
}
public static No2AllReactSlot ofClass(Class<?> scriptClz) {
return new No2AllReactSlot(null, scriptClz.getPackageName() + ":type=" + scriptClz.getSimpleName());
}
public static No2AllReactSlot of(No2AllReactSlot parent, String kvPair) {
return new No2AllReactSlot(parent, kvPair);
}
}

View file

@ -0,0 +1,7 @@
package love.distributedrebirth.no2all.react;
public final class No2AllReactSlotLoad {
public No2AllReactSlotLoad() {
}
}

View file

@ -0,0 +1,30 @@
package love.distributedrebirth.no2all.react;
public final class No2AllReactSlotSignal<T> {
private final No2AllReactSlot target;
private final T data;
private final No2AllReact react;
public No2AllReactSlotSignal(No2AllReactSlot target, T data, No2AllReact react) {
this.target = target;
this.data = data;
this.react = react;
}
public No2AllReactSlot getTarget() {
return target;
}
public T getData() {
return data;
}
public No2AllReact getReact() {
return react;
}
// public T $() {
// return getData();
// }
}

View file

@ -0,0 +1,7 @@
package love.distributedrebirth.no2all.react;
public interface No2AllReactTypeScript extends No2AllReactListener<No2AllReactSlotLoad> {
default void onRelease(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
}
}

View file

@ -0,0 +1,16 @@
package love.distributedrebirth.no2all.react.warp;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
public abstract class No2AllActAbstractSlot {
private final No2AllReactSlot slot;
public No2AllActAbstractSlot(No2AllReactSlot slot) {
this.slot = slot;
}
public final No2AllReactSlot getSlot() {
return slot;
}
}

View file

@ -0,0 +1,10 @@
package love.distributedrebirth.no2all.react.warp;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
public final class No2AllArtWarpSlotAdd extends No2AllActAbstractSlot {
protected No2AllArtWarpSlotAdd(No2AllReactSlot slot) {
super(slot);
}
}

View file

@ -0,0 +1,10 @@
package love.distributedrebirth.no2all.react.warp;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
public final class No2AllArtWarpSlotRemove extends No2AllActAbstractSlot {
protected No2AllArtWarpSlotRemove(No2AllReactSlot slot) {
super(slot);
}
}

View file

@ -0,0 +1,29 @@
package love.distributedrebirth.no2all.react.warp;
import java.util.ArrayList;
import java.util.List;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
public class No2AllReactSlotContract {
private final No2AllReactSlot slot;
final List<Class<?>> slotTypesIn = new ArrayList<>();
final List<Class<?>> slotTypesOut = new ArrayList<>();
public No2AllReactSlotContract(No2AllReactSlot slot) {
this.slot = slot;
}
public No2AllReactSlot getSlot() {
return slot;
}
public List<Class<?>> getSlotTypesIn() {
return slotTypesIn;
}
public List<Class<?>> getSlotTypesOut() {
return slotTypesOut;
}
}

View file

@ -0,0 +1,186 @@
package love.distributedrebirth.no2all.react.warp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import love.distributedrebirth.no2all.react.No2AllReact;
import love.distributedrebirth.no2all.react.No2AllReactListener;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
public class No2AllReactWarpCore implements No2AllReact {
public static final No2AllReactSlot DILITHIUM = No2AllReactSlot.ofClass(No2AllReactWarpCore.class);
private final Map<No2AllReactSlot, No2AllReactWarpFuel> slots = new HashMap<>();
private final Map<Class<?>, Object> services = new HashMap<>();
private final List<BacklogEvent> backlog = new ArrayList<>();
private Object currentEvent = null;
public No2AllReactWarpCore() {
claim(DILITHIUM);
toWarpFuel(DILITHIUM).registrateTypeIn(No2AllReactSlotLoad.class);
toWarpFuel(DILITHIUM).registrateTypeOut(No2AllArtWarpSlotAdd.class);
toWarpFuel(DILITHIUM).registrateTypeOut(No2AllArtWarpSlotRemove.class);
}
public void load(No2AllReactTypeScript script) {
Objects.requireNonNull(script).onEvent(new No2AllReactSlotSignal<>(DILITHIUM, new No2AllReactSlotLoad(), this));
}
public No2AllReactSlotContract getSlotContract(No2AllReactSlot slot) {
return toWarpFuel(slot).readContract();
}
public List<No2AllReactSlot> listChilds(No2AllReactSlot slot) {
Objects.requireNonNull(slot);
List<No2AllReactSlot> result = new ArrayList<>();
synchronized (slots) {
for (No2AllReactSlot slug : slots.keySet()) {
if (slot == null) {
result.add(slug);
continue;
}
if (slug.getParent() == null) {
continue;
}
if (slug.getParent().getSlotPath().equals(slot.getSlotPath())) {
result.add(slug);
}
}
}
return result;
}
@Override
public void fireForEach(No2AllReactSlot slot, Object event) {
for (No2AllReactSlot target : listChilds(slot)) {
fire(target, event);
}
}
@Override
public void fire(No2AllReactSlot slot, Object event) {
Objects.requireNonNull(slot);
Objects.requireNonNull(event);
if (currentEvent != null) {
backlog.add(new BacklogEvent(slot, event));
return;
}
currentEvent = event;
try {
toWarpFuel(slot).fire(event, slot);
while (!backlog.isEmpty()) {
List<BacklogEvent> backlog2 = new ArrayList<>(backlog);
backlog.clear();
for (BacklogEvent next : backlog2) {
toWarpFuel(next.slot).fire(next.event, next.slot);
}
}
} finally {
currentEvent = null;
}
}
static class BacklogEvent {
No2AllReactSlot slot;
Object event;
public BacklogEvent(No2AllReactSlot slot, Object event) {
this.slot = slot;
this.event = event;
}
}
@SuppressWarnings("unchecked")
@Override
public <T> void registrate(No2AllReactSlot slot, Class<T> eventType, No2AllReactListener<T> listener) {
No2AllReactListener<Object> listenerObj = (No2AllReactListener<Object>) listener;
toWarpFuel(slot).registrateListener(eventType, listenerObj);
}
@Override
public void release(No2AllReactSlot slot) {
toWarpFuel(slot).removeAll();
synchronized (slots) {
slots.remove(slot);
}
fire(DILITHIUM, new No2AllArtWarpSlotRemove(slot));
}
@Override
public void claim(No2AllReactSlot slot) {
Objects.requireNonNull(slot);
synchronized (slots) {
if (slots.keySet().contains(slot)) {
throw new IllegalStateException("Slug already claimed: " + slot.getSlotPath());
}
slots.put(slot, new No2AllReactWarpFuel(this, slot));
}
fire(DILITHIUM, new No2AllArtWarpSlotAdd(slot));
}
@Override
public void claimOut(No2AllReactSlot slot, Class<?> eventType) {
toWarpFuel(slot).registrateTypeOut(eventType);
}
@Override
public void claimIn(No2AllReactSlot slot, Class<?> eventType) {
toWarpFuel(slot).registrateTypeIn(eventType);
}
@Override
public void requireSlot(No2AllReactSlot slot, No2AllReactSlot dep) {
if (!isClaimed(dep)) {
throw new IllegalStateException("Script dependency missing: " + dep);
}
toWarpFuel(slot).addRequireSlot(dep);
}
@Override
public void requireService(No2AllReactSlot slot, Class<?> serviceType) {
toWarpFuel(slot).addRequireService(serviceType);
}
@SuppressWarnings("unchecked")
@Override
public <T> T service(Class<T> serviceType) {
Objects.requireNonNull(serviceType);
synchronized (services) {
return (T) services.get(serviceType);
}
}
public <T> void addService(Class<T> serviceType, T service) {
Objects.requireNonNull(serviceType);
Objects.requireNonNull(service);
synchronized (services) {
services.put(serviceType, service);
}
}
public boolean isClaimed(No2AllReactSlot slug) {
Objects.requireNonNull(slug);
synchronized (slots) {
return slots.keySet().contains(slug);
}
}
protected No2AllReactWarpFuel toWarpFuel(No2AllReactSlot slot) {
Objects.requireNonNull(slot);
No2AllReactWarpFuel result;
synchronized (slots) {
result = slots.get(slot);
if (result == null) {
throw new IllegalStateException("Slot not claimed: " + slot.getSlotPath());
}
}
return result;
}
}

View file

@ -0,0 +1,120 @@
package love.distributedrebirth.no2all.react.warp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import love.distributedrebirth.no2all.react.No2AllReactListener;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
public class No2AllReactWarpFuel {
private final No2AllReactWarpCore no2AllReactWarpCore;
private final No2AllReactSlot containerSlot;
private final Map<Class<?>, List<No2AllReactListener<Object>>> listeners = new HashMap<>();
private final Set<Class<?>> claimTypesOut = new HashSet<>();
private final Set<Class<?>> claimTypesIn = new HashSet<>();
private final Set<Class<?>> requireServices = new HashSet<>();
private final Set<No2AllReactSlot> requireSlots = new HashSet<>();
protected No2AllReactWarpFuel(No2AllReactWarpCore no2AllReactWarpCore, No2AllReactSlot containerSlot) {
this.no2AllReactWarpCore = Objects.requireNonNull(no2AllReactWarpCore);
this.containerSlot = Objects.requireNonNull(containerSlot);
}
private List<No2AllReactListener<Object>> toViewOfListeners(Class<?> eventType) {
List<No2AllReactListener<Object>> result = new ArrayList<>();
synchronized (listeners) {
List<No2AllReactListener<Object>> typeListeners = listeners.get(eventType);
if (typeListeners == null) {
return result;
}
result.addAll(typeListeners);
}
return result;
}
public void fire(Object event, No2AllReactSlot slot) {
for (No2AllReactListener<Object> listener : toViewOfListeners(event.getClass())) {
listener.onEvent(new No2AllReactSlotSignal<>(slot, event, this.no2AllReactWarpCore));
}
}
public void registrateListener(Class<?> eventType, No2AllReactListener<Object> listener) {
Objects.requireNonNull(eventType);
Objects.requireNonNull(listener);
synchronized (listeners) {
List<No2AllReactListener<Object>> typeListeners = listeners.get(eventType);
if (typeListeners == null) {
typeListeners = new ArrayList<>();
listeners.put(eventType, typeListeners);
}
typeListeners.add(listener);
}
}
public void registrateTypeOut(Class<?> eventType) {
Objects.requireNonNull(eventType);
synchronized (claimTypesOut) {
claimTypesOut.add(eventType);
}
}
public void registrateTypeIn(Class<?> eventType) {
Objects.requireNonNull(eventType);
synchronized (claimTypesIn) {
claimTypesIn.add(eventType);
}
}
public No2AllReactSlotContract readContract() {
No2AllReactSlotContract result = new No2AllReactSlotContract(containerSlot);
synchronized (claimTypesIn) {
result.slotTypesIn.addAll(claimTypesIn);
}
synchronized (claimTypesOut) {
result.slotTypesOut.addAll(claimTypesOut);
}
return result;
}
public void addRequireService(Class<?> serviceType) {
Objects.requireNonNull(serviceType);
synchronized (requireServices) {
requireServices.add(serviceType);
}
}
public void addRequireSlot(No2AllReactSlot dep) {
Objects.requireNonNull(dep);
synchronized (requireSlots) {
requireSlots.add(dep);
}
}
public void removeAll() {
synchronized (listeners) {
for (Class<?> eventType : listeners.keySet()) {
List<No2AllReactListener<Object>> typeListeners = listeners.get(eventType);
typeListeners.clear();
}
}
synchronized (claimTypesOut) {
claimTypesOut.clear();
}
synchronized (claimTypesIn) {
claimTypesIn.clear();
}
synchronized (requireServices) {
requireServices.clear();
}
synchronized (requireSlots) {
requireSlots.clear();
}
}
}

View file

@ -0,0 +1,30 @@
package love.distributedrebirth.no2all.react.warp;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import java.util.logging.Logger;
import love.distributedrebirth.no2all.react.No2AllReact;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
public class No2AllRtsWarpSpeedMonitor implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(No2AllRtsWarpSpeedMonitor.class);
private static final No2AllReactSlot API_DILITHIUM = No2AllReactWarpCore.DILITHIUM;
private static final Logger LOG = Logger.getLogger(No2AllRtsWarpSpeedMonitor.class.getName());
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
No2AllReact react = signal.getReact();
react.claim(API);
react.requireSlot(API, API_DILITHIUM);
react.registrate(API_DILITHIUM, No2AllArtWarpSlotAdd.class, v -> {
LOG.fine("slot-add: " + v.getData().getSlot().getSlotPath());
});
react.registrate(API_DILITHIUM, No2AllArtWarpSlotRemove.class, v -> {
LOG.fine("slot-remove: " + v.getData().getSlot().getSlotPath());
});
}
}

View file

@ -0,0 +1,70 @@
package love.distributedrebirth.no2all.wire.jetty;
import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutionException;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.websocket.client.impl.JettyClientUpgradeRequest;
import love.distributedrebirth.no2all.wire.WireClient;
import love.distributedrebirth.no2all.wire.WireClientHandler;
public class JettyWireClient implements WireClient {
private final URI uri;
private final WebSocketClient client;
private final JettyWireClientHandler handler;
protected JettyWireClient(URI uri, WebSocketClient client, WireClientHandler handler) {
this.uri = uri;
this.client = client;
this.handler = new JettyWireClientHandler(handler);
}
public JettyWireClientHandler getHandler() {
return handler;
}
@Override
public void connect() {
try {
client.connect(handler, uri).get();
} catch (IOException | InterruptedException | ExecutionException e) {
throw new IllegalStateException(e);
}
}
@Override
public void close(int code, String message) {
client.getOpenSessions().forEach(v -> {
JettyClientUpgradeRequest req = JettyClientUpgradeRequest.class.cast(v.getUpgradeRequest());
if (req.getURI().equals(uri)) {
v.close(code, message);
}
});
}
@Override
public void sendMessage(String message) {
client.getOpenSessions().forEach(v -> {
try {
v.getRemote().sendString(message);
} catch (IOException e) {
throw new IllegalStateException(e);
}
});
}
@Override
public void sendBinary(ByteBuffer message) {
client.getOpenSessions().forEach(v -> {
try {
v.getRemote().sendBytes(message);
} catch (IOException e) {
throw new IllegalStateException(e);
}
});
}
}

View file

@ -0,0 +1,30 @@
package love.distributedrebirth.no2all.wire.jetty;
import java.net.URI;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import love.distributedrebirth.no2all.wire.WireClient;
import love.distributedrebirth.no2all.wire.WireClientEndpoint;
import love.distributedrebirth.no2all.wire.WireClientHandler;
public class JettyWireClientEndpoint implements WireClientEndpoint {
private final URI uri;
private final WebSocketClient client;
public JettyWireClientEndpoint(URI uri, WebSocketClient client) {
this.uri = uri;
this.client = client;
}
@Override
public String wireId() {
return uri.toString();
}
@Override
public WireClient wireClient(WireClientHandler handler) {
return new JettyWireClient(uri, client, handler);
}
}

View file

@ -0,0 +1,43 @@
package love.distributedrebirth.no2all.wire.jetty;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketListener;
import love.distributedrebirth.no2all.wire.WireClientHandler;
public class JettyWireClientHandler implements WebSocketListener {
private final WireClientHandler handler;
protected JettyWireClientHandler(WireClientHandler handler) {
this.handler = handler;
this.handler.onStart();
}
@Override
public void onWebSocketConnect(Session session) {
handler.onOpen();
}
@Override
public void onWebSocketClose(int statusCode, String reason) {
handler.onClose(statusCode, reason, false);
}
@Override
public void onWebSocketError(Throwable cause) {
handler.onError(cause);
}
@Override
public void onWebSocketBinary(byte[] payload, int offset, int len) {
handler.onBinary(ByteBuffer.wrap(payload, offset, len));
}
@Override
public void onWebSocketText(String message) {
handler.onMessage(message);
}
}

View file

@ -0,0 +1,41 @@
package love.distributedrebirth.no2all.wire.jetty;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer;
import love.distributedrebirth.no2all.wire.WireServer;
import love.distributedrebirth.no2all.wire.WireServerHandler;
public class JettyWireServer implements WireServer {
private final JettyWebSocketServerContainer wsContainer;
protected JettyWireServer(JettyWebSocketServerContainer wsContainer, String servletPath, WireServerHandler handler) {
this.wsContainer = wsContainer;
this.wsContainer.addMapping(servletPath, new JettyWireServerEndpointCreator(handler));
}
@Override
public void broadcastMessage(String message) {
wsContainer.getOpenSessions().forEach(v -> {
try {
v.getRemote().sendString(message);
} catch (IOException e) {
throw new IllegalStateException(e);
}
});
}
@Override
public void broadcastBinary(ByteBuffer message) {
wsContainer.getOpenSessions().forEach(v -> {
try {
v.getRemote().sendBytes(message);
} catch (IOException e) {
throw new IllegalStateException(e);
}
});
}
}

View file

@ -0,0 +1,28 @@
package love.distributedrebirth.no2all.wire.jetty;
import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer;
import love.distributedrebirth.no2all.wire.WireServer;
import love.distributedrebirth.no2all.wire.WireServerEndpoint;
import love.distributedrebirth.no2all.wire.WireServerHandler;
public class JettyWireServerEndpoint implements WireServerEndpoint {
private final JettyWebSocketServerContainer wsContainer;
private final String servletPath;
public JettyWireServerEndpoint(JettyWebSocketServerContainer wsContainer, String servletPath) {
this.wsContainer = wsContainer;
this.servletPath = servletPath;
}
@Override
public String wireId() {
return servletPath;
}
@Override
public WireServer wireServer(WireServerHandler handler) {
return new JettyWireServer(wsContainer, servletPath, handler);
}
}

View file

@ -0,0 +1,22 @@
package love.distributedrebirth.no2all.wire.jetty;
import org.eclipse.jetty.websocket.server.JettyServerUpgradeRequest;
import org.eclipse.jetty.websocket.server.JettyServerUpgradeResponse;
import org.eclipse.jetty.websocket.server.JettyWebSocketCreator;
import love.distributedrebirth.no2all.wire.WireServerHandler;
public class JettyWireServerEndpointCreator implements JettyWebSocketCreator {
private final WireServerHandler handler;
public JettyWireServerEndpointCreator(WireServerHandler handler) {
this.handler = handler;
}
@Override
public Object createWebSocket(JettyServerUpgradeRequest jettyServerUpgradeRequest,
JettyServerUpgradeResponse jettyServerUpgradeResponse) {
return new JettyWireServerHandler(handler);
}
}

View file

@ -0,0 +1,45 @@
package love.distributedrebirth.no2all.wire.jetty;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketListener;
import love.distributedrebirth.no2all.wire.WireServerHandler;
public class JettyWireServerHandler implements WebSocketListener {
private final WireServerHandler handler;
private JettyWireServerSocket conn;
protected JettyWireServerHandler(WireServerHandler handler) {
this.handler = handler;
this.handler.onStart();
}
@Override
public void onWebSocketConnect(Session session) {
this.conn = new JettyWireServerSocket(session);
handler.onOpen(conn);
}
@Override
public void onWebSocketClose(int statusCode, String reason) {
handler.onClose(conn, statusCode, reason, false);
}
@Override
public void onWebSocketError(Throwable cause) {
handler.onError(conn, cause);
}
@Override
public void onWebSocketBinary(byte[] payload, int offset, int len) {
handler.onBinary(conn, ByteBuffer.wrap(payload, offset, len));
}
@Override
public void onWebSocketText(String message) {
handler.onMessage(conn, message);
}
}

View file

@ -0,0 +1,45 @@
package love.distributedrebirth.no2all.wire.jetty;
import java.io.IOException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.api.Session;
import love.distributedrebirth.no2all.wire.WireServerSocket;
public final class JettyWireServerSocket implements WireServerSocket {
private final Session session;
protected JettyWireServerSocket(Session session) {
this.session = session;
}
@Override
public String getRemoteAddress() {
return session.getRemoteAddress().toString();
}
@Override
public void sendMessage(String message) {
try {
session.getRemote().sendString(message);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
@Override
public void sendBinary(ByteBuffer message) {
try {
session.getRemote().sendBytes(message);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
@Override
public void close(int code, String message) {
session.close(code, message);
}
}

View file

@ -0,0 +1,77 @@
package love.distributedrebirth.no2all.wire.jetty;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import love.distributedrebirth.no2all.wire.WireClient;
import love.distributedrebirth.no2all.wire.WireClientHandler;
public class EventClient implements WireClientHandler {
private static final Logger LOG = LoggerFactory.getLogger(EventClient.class);
public static void main(String[] args) throws Exception {
EventClient client = new EventClient();
client.start();
client.sendHallo();
client.stop();
}
private WebSocketClient client;
private JettyWireClientEndpoint endpoint1;
public EventClient() throws URISyntaxException {
client = new WebSocketClient();
endpoint1 = new JettyWireClientEndpoint(new URI("ws://localhost:8080"), client);
}
public void start() throws Exception {
client.start();
LOG.info("client startup");
}
public void stop() throws Exception {
client.stop();
}
public void sendHallo() {
WireClient client1 = endpoint1.wireClient(this);
client1.connect();
client1.sendMessage("test me");
}
@Override
public void onStart() {
LOG.info("client.onStart()");
}
@Override
public void onOpen() {
LOG.info("client.onOpen()");
}
@Override
public void onClose(int code, String reason, boolean remote) {
LOG.info("client.onClose: "+code);
}
@Override
public void onError(Throwable error) {
LOG.info("client.onError: "+error.getMessage());
}
@Override
public void onMessage(String message) {
LOG.info("client.onMessage: "+message);
}
@Override
public void onBinary(ByteBuffer message) {
LOG.info("client.onBinary: "+message);
}
}

View file

@ -0,0 +1,102 @@
package love.distributedrebirth.no2all.wire.jetty;
import java.net.URI;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.component.LifeCycle.Listener;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.warp.No2AllReactWarpCore;
import love.distributedrebirth.no2all.react.warp.No2AllRtsWarpSpeedMonitor;
import love.distributedrebirth.no2all.react.wire.server.No2AllActServer;
import love.distributedrebirth.no2all.react.wire.server.No2AllActServerSocketSendMessage;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServer;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServerSocket;
import love.distributedrebirth.no2all.react.wire.server.No2AllArtServerSocketOnMessage;
import love.distributedrebirth.no2all.react.wire.server.No2AllRtsServerLog;
import love.distributedrebirth.no2all.react.wire.server.No2AllRtsServer;
public class EventServer {
private static final Logger LOG = LoggerFactory.getLogger(EventServer.class);
public static void main(String[] args) throws Exception {
EventServer server = new EventServer();
server.setPort(8080);
server.start();
server.join();
}
private final Server server;
private final ServerConnector connector;
private JettyWireServerEndpoint endpoint1;
private JettyWireServerEndpoint endpoint2;
private JettyWireServerEndpoint endpoint3;
public EventServer() {
server = new Server();
connector = new ServerConnector(server);
server.addConnector(connector);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
JettyWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) -> {
wsContainer.setMaxTextMessageSize(65535);
endpoint1 = new JettyWireServerEndpoint(wsContainer, "/");
endpoint2 = new JettyWireServerEndpoint(wsContainer, "/event");
endpoint3 = new JettyWireServerEndpoint(wsContainer, "/other");
});
server.addEventListener(new Listener() {
@Override
public void lifeCycleStarted(LifeCycle event) {
LOG.info("Startup No2AllReactWarpCore");
No2AllReactWarpCore react = new No2AllReactWarpCore();
react.load(new No2AllRtsWarpSpeedMonitor());
react.load(new No2AllRtsServer());
react.load(new No2AllRtsServerLog());
// auto reply
react.registrate(No2AllRtsServer.API, No2AllArtServer.class, artServer -> {
No2AllReactSlot serverSlot = artServer.getData().getSlot();
react.registrate(serverSlot, No2AllArtServerSocket.class, artSocket -> {
No2AllReactSlot socketSlot = artSocket.getData().getSlot();
react.registrate(socketSlot, No2AllArtServerSocketOnMessage.class, artMsg -> {
react.fire(socketSlot, new No2AllActServerSocketSendMessage("RE: "+artMsg.getData().getMessage()));
});
});
});
react.fire(No2AllRtsServer.API, new No2AllActServer(endpoint1));
react.fire(No2AllRtsServer.API, new No2AllActServer(endpoint2));
react.fire(No2AllRtsServer.API, new No2AllActServer(endpoint3));
}
});
}
public void setPort(int port) {
connector.setPort(port);
}
public void start() throws Exception {
server.start();
}
public URI getURI() {
return server.getURI();
}
public void stop() throws Exception {
server.stop();
}
public void join() throws InterruptedException {
LOG.info("Use Ctrl+C to stop server");
server.join();
}
}

View file

@ -0,0 +1,54 @@
package love.distributedrebirth.no2all.wire.jre;
import java.net.URI;
import java.net.http.WebSocket;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutionException;
import love.distributedrebirth.no2all.wire.WireClient;
import love.distributedrebirth.no2all.wire.WireClientHandler;
public final class JreWireClient implements WireClient {
private final URI uri;
private final WebSocket.Builder wsBuilder;
private final WireClientHandler handler;
private WebSocket webSocket;
protected JreWireClient(URI uri, WebSocket.Builder wsBuilder, WireClientHandler handler) {
this.uri = uri;
this.wsBuilder = wsBuilder;
this.handler = handler;
}
@Override
public void connect() {
try {
webSocket = wsBuilder.buildAsync(uri, new JreWireClientHandler(handler)).get();
} catch (InterruptedException | ExecutionException error) {
handler.onError(error); // handles: Connection refused
}
}
@Override
public void close(int code, String message) {
if (webSocket != null) {
webSocket.sendClose(code, message);
webSocket = null;
}
}
@Override
public void sendMessage(String message) {
if (webSocket != null) {
webSocket.sendText(message, true);
}
}
@Override
public void sendBinary(ByteBuffer message) {
if (webSocket != null) {
webSocket.sendBinary(message, true);
}
}
}

View file

@ -0,0 +1,29 @@
package love.distributedrebirth.no2all.wire.jre;
import java.net.URI;
import java.net.http.WebSocket;
import love.distributedrebirth.no2all.wire.WireClient;
import love.distributedrebirth.no2all.wire.WireClientEndpoint;
import love.distributedrebirth.no2all.wire.WireClientHandler;
public final class JreWireClientEndpoint implements WireClientEndpoint {
private final URI uri;
private final WebSocket.Builder wsBuilder;
public JreWireClientEndpoint(URI uri, WebSocket.Builder wsBuilder) {
this.wsBuilder = wsBuilder;
this.uri = uri;
}
@Override
public String wireId() {
return uri.toString();
}
@Override
public WireClient wireClient(WireClientHandler handler) {
return new JreWireClient(uri, wsBuilder, handler);
}
}

View file

@ -0,0 +1,46 @@
package love.distributedrebirth.no2all.wire.jre;
import java.net.http.WebSocket;
import java.nio.ByteBuffer;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import love.distributedrebirth.no2all.wire.WireClientHandler;
public final class JreWireClientHandler implements WebSocket.Listener {
private final WireClientHandler handler;
protected JreWireClientHandler(WireClientHandler handler) {
this.handler = handler;
this.handler.onStart();
}
@Override
public void onOpen(WebSocket ws) {
handler.onOpen();
}
@Override
public CompletionStage<?> onClose(WebSocket ws, int code, String reason) {
handler.onClose(code, reason, true);
return CompletableFuture.completedFuture("");
}
@Override
public void onError(WebSocket ws, Throwable error) {
handler.onError(error);
}
@Override
public CompletionStage<?> onText(WebSocket ws, CharSequence data, boolean last) {
handler.onMessage(data.toString());
return CompletableFuture.completedFuture("");
}
@Override
public CompletionStage<?> onBinary(WebSocket ws, ByteBuffer data, boolean last) {
handler.onBinary(data);
return CompletableFuture.completedFuture("");
}
}

View file

@ -0,0 +1,42 @@
package love.distributedrebirth.no2all.wire.ojw;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.Map;
import love.distributedrebirth.no2all.wire.WireClient;
import love.distributedrebirth.no2all.wire.WireClientHandler;
public class OjwWireClient implements WireClient {
private final OjwWireClientHandler handler;
protected OjwWireClient(URI uri, Map<String, String> headers, int timeoutMs, WireClientHandler wireHandler) {
this.handler = new OjwWireClientHandler(uri, headers, timeoutMs, wireHandler);
wireHandler.onStart();
}
public OjwWireClientHandler getHandler() {
return handler;
}
@Override
public void connect() {
handler.connect();
}
@Override
public void close(int code, String message) {
handler.close(code, message);
}
@Override
public void sendMessage(String message) {
handler.send(message);
}
@Override
public void sendBinary(ByteBuffer message) {
handler.send(message);
}
}

View file

@ -0,0 +1,35 @@
package love.distributedrebirth.no2all.wire.ojw;
import java.net.URI;
import java.util.Map;
import love.distributedrebirth.no2all.wire.WireClient;
import love.distributedrebirth.no2all.wire.WireClientEndpoint;
import love.distributedrebirth.no2all.wire.WireClientHandler;
public class OjwWireClientEndpoint implements WireClientEndpoint {
private final URI uri;
private final Map<String, String> headers;
private final int timeoutMs;
public OjwWireClientEndpoint(URI uri) {
this(uri, null, 60 * 1000);
}
public OjwWireClientEndpoint(URI uri, Map<String, String> headers, int timeoutMs) {
this.uri = uri;
this.headers = headers;
this.timeoutMs = timeoutMs;
}
@Override
public String wireId() {
return uri.toString();
}
@Override
public WireClient wireClient(WireClientHandler handler) {
return new OjwWireClient(uri, headers, timeoutMs, handler);
}
}

View file

@ -0,0 +1,46 @@
package love.distributedrebirth.no2all.wire.ojw;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.Map;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.handshake.ServerHandshake;
import love.distributedrebirth.no2all.wire.WireClientHandler;
public class OjwWireClientHandler extends WebSocketClient {
private final WireClientHandler handler;
protected OjwWireClientHandler(URI uri, Map<String, String> headers, int timeoutMs, WireClientHandler handler) {
super(uri, new Draft_6455(), headers, timeoutMs);
this.handler = handler;
}
@Override
public void onOpen(ServerHandshake handshakedata) {
handler.onOpen();
}
@Override
public void onClose(int code, String reason, boolean remote) {
handler.onClose(code, reason, remote);
}
@Override
public void onError(Exception ex) {
handler.onError(ex);
}
@Override
public void onMessage(String message) {
handler.onMessage(message);
}
@Override
public void onMessage(ByteBuffer message) {
handler.onBinary(message);
}
}

View file

@ -0,0 +1,31 @@
package love.distributedrebirth.no2all.wire.ojw;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import love.distributedrebirth.no2all.wire.WireServer;
import love.distributedrebirth.no2all.wire.WireServerHandler;
public class OjwWireServer implements WireServer {
private final OjwWireServerHandler handler;
protected OjwWireServer(InetSocketAddress port, int pingTimeoutSecs, WireServerHandler handler) {
this.handler = new OjwWireServerHandler(port, pingTimeoutSecs, handler);
this.handler.start();
}
public OjwWireServerHandler getHandler() {
return handler;
}
@Override
public void broadcastMessage(String message) {
handler.broadcast(message);
}
@Override
public void broadcastBinary(ByteBuffer message) {
handler.broadcast(message);
}
}

View file

@ -0,0 +1,28 @@
package love.distributedrebirth.no2all.wire.ojw;
import java.net.InetSocketAddress;
import love.distributedrebirth.no2all.wire.WireServer;
import love.distributedrebirth.no2all.wire.WireServerEndpoint;
import love.distributedrebirth.no2all.wire.WireServerHandler;
public class OjwWireServerEndpoint implements WireServerEndpoint {
private final InetSocketAddress port;
private final int pingTimeoutSecs;
public OjwWireServerEndpoint(InetSocketAddress port, int pingTimeoutSecs) {
this.port = port;
this.pingTimeoutSecs = pingTimeoutSecs;
}
@Override
public String wireId() {
return port.toString();
}
@Override
public WireServer wireServer(WireServerHandler handler) {
return new OjwWireServer(port, pingTimeoutSecs, handler);
}
}

View file

@ -0,0 +1,81 @@
package love.distributedrebirth.no2all.wire.ojw;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import love.distributedrebirth.no2all.wire.WireServerHandler;
public class OjwWireServerHandler extends WebSocketServer {
private final WireServerHandler handler;
private final Map<WebSocket, OjwWireServerSocket> wraps = new WeakHashMap<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock lockRead = lock.readLock();
private final Lock lockWrite = lock.writeLock();
protected OjwWireServerHandler(InetSocketAddress port, int pingTimeoutSecs, WireServerHandler handler) {
super(port);
setConnectionLostTimeout(pingTimeoutSecs);
this.handler = handler;
}
@Override
public void onStart() {
handler.onStart();
}
@Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
handler.onOpen(wrap(conn));
}
@Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
handler.onClose(wrap(conn), code, reason, remote);
}
@Override
public void onError(WebSocket conn, Exception ex) {
handler.onError(wrap(conn), ex);
}
@Override
public void onMessage(WebSocket conn, String message) {
handler.onMessage(wrap(conn), message);
}
@Override
public void onMessage(WebSocket conn, ByteBuffer message) {
handler.onBinary(wrap(conn), message);
}
private OjwWireServerSocket wrap(WebSocket conn) {
OjwWireServerSocket result = null;
lockRead.lock();
try {
result = wraps.get(conn);
} finally {
lockRead.unlock();
}
if (result != null) {
return result;
}
result = new OjwWireServerSocket(conn);
lockWrite.lock();
try {
wraps.put(conn, result);
} finally {
lockWrite.unlock();
}
return result;
}
}

View file

@ -0,0 +1,36 @@
package love.distributedrebirth.no2all.wire.ojw;
import java.nio.ByteBuffer;
import org.java_websocket.WebSocket;
import love.distributedrebirth.no2all.wire.WireServerSocket;
public final class OjwWireServerSocket implements WireServerSocket {
private final WebSocket socket;
protected OjwWireServerSocket(WebSocket socket) {
this.socket = socket;
}
@Override
public String getRemoteAddress() {
return socket.getRemoteSocketAddress().getAddress().getHostAddress();
}
@Override
public void sendMessage(String message) {
socket.send(message);
}
@Override
public void sendBinary(ByteBuffer message) {
socket.send(message);
}
@Override
public void close(int code, String message) {
socket.close(code, message);
}
}

View file

@ -0,0 +1,14 @@
package love.distributedrebirth.no2all.wire;
import java.nio.ByteBuffer;
public interface WireClient {
void connect();
void close(int code, String message);
void sendMessage(String message);
void sendBinary(ByteBuffer message);
}

View file

@ -0,0 +1,8 @@
package love.distributedrebirth.no2all.wire;
public interface WireClientEndpoint {
String wireId();
WireClient wireClient(WireClientHandler handler);
}

View file

@ -0,0 +1,18 @@
package love.distributedrebirth.no2all.wire;
import java.nio.ByteBuffer;
public interface WireClientHandler {
void onStart();
void onOpen();
void onClose(int code, String reason, boolean remote);
void onError(Throwable error);
void onMessage(String message);
void onBinary(ByteBuffer message);
}

View file

@ -0,0 +1,10 @@
package love.distributedrebirth.no2all.wire;
import java.nio.ByteBuffer;
public interface WireServer {
void broadcastMessage(String message);
void broadcastBinary(ByteBuffer message);
}

View file

@ -0,0 +1,8 @@
package love.distributedrebirth.no2all.wire;
public interface WireServerEndpoint {
String wireId();
WireServer wireServer(WireServerHandler handler);
}

View file

@ -0,0 +1,18 @@
package love.distributedrebirth.no2all.wire;
import java.nio.ByteBuffer;
public interface WireServerHandler {
void onStart();
void onOpen(WireServerSocket conn);
void onClose(WireServerSocket conn, int code, String reason, boolean remote);
void onError(WireServerSocket conn, Throwable error);
void onMessage(WireServerSocket conn, String message);
void onBinary(WireServerSocket conn, ByteBuffer message);
}

View file

@ -0,0 +1,14 @@
package love.distributedrebirth.no2all.wire;
import java.nio.ByteBuffer;
public interface WireServerSocket {
String getRemoteAddress();
void sendMessage(String message);
void sendBinary(ByteBuffer message);
void close(int code, String message);
}

View file

@ -0,0 +1,4 @@
package love.distributedrebirth.no2all.wire.fetch;
public interface WireFetch extends Runnable {
}

View file

@ -0,0 +1,6 @@
package love.distributedrebirth.no2all.wire.fetch;
public interface WireFetchFactory {
WireFetch buildFetcher(WireFetchResource resource, WireFetchHandler handler);
}

View file

@ -0,0 +1,84 @@
package love.distributedrebirth.no2all.wire.fetch;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.Map.Entry;
public final class WireFetchFactoryDefault implements WireFetchFactory {
@Override
public WireFetch buildFetcher(WireFetchResource resource, WireFetchHandler handler) {
return new HttpDownloader(resource, handler);
}
static protected final class HttpDownloader implements WireFetch {
private final WireFetchResource resource;
private final WireFetchHandler handler;
protected HttpDownloader(WireFetchResource resource, WireFetchHandler handler) {
this.resource = resource;
this.handler = handler;
}
@Override
public void run() {
try {
handler.onStart();
try (InputStream conn = openInputStream(resource.getUrId().toURL(), resource.getHeaders(), resource.getTimeoutMs(), 5)) {
try (ByteArrayOutputStream result = new ByteArrayOutputStream()) {
int totalBytes = 0;
byte[] buffer = new byte[4096];
int length;
while ((length = conn.read(buffer)) != -1) {
result.write(buffer, 0, length);
totalBytes += length;
handler.onProgress(totalBytes);
}
handler.onReady(ByteBuffer.wrap(result.toByteArray()));
}
}
} catch (Exception error) {
handler.onError(error);
}
}
private InputStream openInputStream(URL url, Map<String, String> args, int timeoutMs, int redirectLimit) throws IOException {
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(timeoutMs);
con.setReadTimeout(timeoutMs);
if (args != null) {
for (Entry<String, String> e : args.entrySet()) {
con.setRequestProperty(e.getKey(), e.getValue());
}
}
con.connect();
int responseCode = con.getResponseCode();
if (responseCode < 400 && responseCode > 299) {
// for redirects but breaks switch protocols
redirectLimit--;
if (redirectLimit == 0) {
throw new IllegalStateException("Max redirect limit reached");
}
String redirectLocation = con.getHeaderField("Location");
if (redirectLocation == null) {
throw new IllegalStateException("No redirect location header");
}
URL redirectUrl = null;
try {
redirectUrl = new URL(redirectLocation);
} catch (MalformedURLException e) {
redirectUrl = new URL(url.getProtocol() + "://" + url.getHost() + redirectLocation);
}
return openInputStream(redirectUrl, args, timeoutMs, redirectLimit);
}
return con.getInputStream();
}
}
}

View file

@ -0,0 +1,14 @@
package love.distributedrebirth.no2all.wire.fetch;
import java.nio.ByteBuffer;
public interface WireFetchHandler {
void onStart();
void onReady(ByteBuffer result);
void onError(Throwable error);
void onProgress(int totalBytes);
}

View file

@ -0,0 +1,39 @@
package love.distributedrebirth.no2all.wire.fetch;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
public final class WireFetchResource {
private final Map<String, String> headers = new HashMap<>();
private final URI uri;
private int timeoutMs = 10;
public WireFetchResource(URI uri) {
this.uri = uri;
this.timeoutMs = 10;
}
public URI getUrId() {
return uri;
}
public int getTimeoutMs() {
return timeoutMs;
}
public Map<String, String> getHeaders() {
return headers;
}
public WireFetchResource withTimeoutMs(int timeoutMs) {
this.timeoutMs = timeoutMs;
return this;
}
public WireFetchResource withHeader(String key, String value) {
headers.put(key, value);
return this;
}
}

View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="90 seconds" debug="false">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<jmxConfigurator/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>logs/no2all-demo.log</file>
<encoder>
<pattern>%date %level [%thread] %logger{10} %msg%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date %level [%thread] %logger{10} %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
</root>
<!-- Package opens. -->
<logger level="DEBUG" name="love.distributedrebirth.no2all.react.warp"/>
<!-- Package limits. -->
<logger level="INFO" name="org.eclipse.jetty"/>
<logger level="INFO" name="jakarta.json.spi"/>
</configuration>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="90 seconds">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
<resetJUL>true</resetJUL>
</contextListener>
<jmxConfigurator/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>logs/no2all-demo.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/no2all-demo-%d{yyyy-MM-dd}.log.zip</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{10} %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
</root>
<!-- Package limits. -->
<logger level="INFO" name="org.eclipse.jetty"/>
</configuration>

View file

@ -0,0 +1,56 @@
package love.distributedrebirth.no2all.zerofungus;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.logging.Logger;
import javax.sql.DataSource;
import jakarta.json.Json;
import jakarta.json.JsonWriter;
import love.distributedrebirth.no2all.nostr.model.event.NoStrEvent;
import love.distributedrebirth.no2all.react.No2AllReact;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
import love.distributedrebirth.no2all.react.nostr.server.relay.NoStrArtServerRelayStoreEvent;
import love.distributedrebirth.no2all.react.nostr.server.relay.NoStrRtsServerRelay;
public class ZFunRtsServer implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(ZFunRtsServer.class);
private static final Logger logger = Logger.getLogger(ZFunRtsServer.class.getName());
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
No2AllReact react = signal.getReact();
react.claim(API);
DataSource ds = react.service(DataSource.class);
react.registrate(NoStrRtsServerRelay.API, NoStrArtServerRelayStoreEvent.class, storeEvent -> {
logger.info("Store event: " + storeEvent.getData().getEvent().getId().getHexDipavali());
NoStrEvent event = storeEvent.getData().getEvent();
StringWriter jsonStr = new StringWriter();
try (JsonWriter writer = Json.createWriter(jsonStr)) {
writer.write(event.toBible());
}
try (Connection conn = ds.getConnection()) {
String sql = "INSERT INTO \"ᔆʸᔆᐪᓫᔿ\".\"ᔆᐪᣔᒼᒽᑉ\" (\"ᑊᑊᐣ\",\"ᣖᓑᒃᒽᑉᓫᔾ\",\"ᒼᣗᓫᣔᐪᓫᐝᒄᐪ\",\"ᑊᑉᑊᣕᒄ\",\"ᒄᓫᒻᐪᣔᕐ\",\"ᓫᕁᣖᑊᣗᓫᐝᒄᐪ\",\"ᣗᣔᒡᒢ\") VALUES (?,?,?,?,?,?,?)";
PreparedStatement prep = conn.prepareStatement(sql);
prep.setString(1, event.getId().getHex());
prep.setString(2, event.getPayload().getPublicKey().getHex());
prep.setDate(3, new java.sql.Date(event.getPayload().getCreatedAt().toEpochMilli()));
prep.setInt(4, event.getPayload().getKind().getNumber());
prep.setString(5, null); // del tag
prep.setString(6, null); // exp date
prep.setString(7, jsonStr.toString());
prep.executeUpdate();
} catch (SQLException e) {
logger.warning(e.getMessage());
}
});
}
}

View file

@ -0,0 +1,23 @@
package love.distributedrebirth.no2all.zerofungus;
import java.util.logging.Logger;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
public class ZFunRtsServerBooted implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(ZFunRtsServerBooted.class);
private static final Logger logger = Logger.getLogger(ZFunRtsServerBooted.class.getName());
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
signal.getReact().claim(API);
logger.info("╔═╗┌─┐┬─┐┌─┐ .╔═╗┬ ┬┌┐┌╔═╗┬ ┬┌─┐");
logger.info("╔═╝├┤ ├┬┘│ │ . ╠╣ │ ││││║ ╦│ │└─┐");
logger.info("╚═╝└─┘┴└─└─┘. ╚ └─┘┘└┘╚═╝└─┘└─┘");
logger.info("Boot done.");
}
}

View file

@ -0,0 +1,78 @@
package love.distributedrebirth.no2all.zerofungus;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import love.distributedrebirth.no2all.react.nostr.client.NoStrRtsClient;
import love.distributedrebirth.no2all.react.nostr.server.NoStrRtsServer;
import love.distributedrebirth.no2all.react.nostr.server.relay.NoStrRtsServerRelay;
import love.distributedrebirth.no2all.react.nostr.server.relay.NoStrRtsServerRelaySubs;
import love.distributedrebirth.no2all.react.warp.No2AllReactWarpCore;
import love.distributedrebirth.no2all.react.warp.No2AllRtsWarpSpeedMonitor;
import love.distributedrebirth.no2all.react.wire.client.No2AllRtsClient;
import love.distributedrebirth.no2all.react.wire.server.No2AllRtsServer;
import love.distributedrebirth.no2all.react.wire.server.No2AllRtsServerLog;
import love.distributedrebirth.no2all.zerofungus.service.ZFunRtsConfigJetty;
import love.distributedrebirth.no2all.zerofungus.service.ZFunRtsConfigLogger;
//import ᒢᐩᐩ.ᔿᐤᒄʸ.ᣔᒃᣔᒼᓑᔆ.BãßBȍőnAbacusInstanceMBeanʸᴰ;
import love.distributedrebirth.no2all.zerofungus.service.ZFunRtsInitJdbc;
public enum ZeroFungus /* implements BãßBȍőnAbacusInstanceMBeanʸᴰ<ZeroFungus> */ {
INSTANCE;
private No2AllReactWarpCore foei = new No2AllReactWarpCore();
private List<ZFunRtsConfigJetty> jetties = new ArrayList<>();
public static void main(String[] args) {
Iterator<String> arguments = Arrays.asList(args).iterator();
boolean hasPort = arguments.hasNext() && arguments.next().equals("-p") && arguments.hasNext();
// todo move
new File("logs").mkdir();
// config jetty
INSTANCE.jetties.clear();
if (hasPort) {
// note: multiple currently does not work...
INSTANCE.jetties.add(Arrays.asList(arguments.next().split(",")).stream().map(v -> Integer.parseInt(v)).findFirst().map(v -> new ZFunRtsConfigJetty(v)).get());
} else {
INSTANCE.jetties.add(new ZFunRtsConfigJetty(8080));
}
INSTANCE.start();
}
public void stop() {
jetties.forEach(v -> v.stop());
// foei.fire(No2AllReactWarpCore.DILITHIUM, new EjectWrapCoreShutdown());
}
public void start() {
// setup logger + warp monitor
foei.load(new ZFunRtsConfigLogger());
foei.load(new No2AllRtsWarpSpeedMonitor());
// add websocket wire support + log
foei.load(new No2AllRtsClient());
foei.load(new No2AllRtsServer());
foei.load(new No2AllRtsServerLog());
// add nostr support
foei.load(new NoStrRtsClient());
foei.load(new NoStrRtsServer());
foei.load(new NoStrRtsServerRelay());
foei.load(new NoStrRtsServerRelaySubs());
// config zero fungus servers and clients
foei.load(new ZFunRtsInitJdbc(foei));
foei.load(new ZFunRtsServer());
// foei.load(new ZFunRtsClientReplay());
// load jetties and join
jetties.forEach(v -> foei.load(v));
foei.load(new ZFunRtsServerBooted());
jetties.stream().findFirst().ifPresent(v -> v.join());
}
}

View file

@ -0,0 +1,133 @@
package love.distributedrebirth.no2all.zerofungus.service;
import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;
import org.eclipse.jetty.server.CustomRequestLog;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.component.LifeCycle.Listener;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceCollection;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.webapp.WebInfConfiguration;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
import love.distributedrebirth.no2all.react.No2AllReact;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
import love.distributedrebirth.no2all.react.wire.server.No2AllActServer;
import love.distributedrebirth.no2all.react.wire.server.No2AllRtsServer;
import love.distributedrebirth.no2all.wire.jetty.JettyWireServerEndpoint;
import love.distributedrebirth.no2all.zerofungus.web.RedirectServlet;
public final class ZFunRtsConfigJetty implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(ZFunRtsConfigJetty.class);
private static final Logger logger = Logger.getLogger(ZFunRtsConfigJetty.class.getName());
private final Server server;
private final ServerConnector connector;
private JettyWireServerEndpoint endpoint1;
private JettyWireServerEndpoint endpoint2;
private JettyWireServerEndpoint endpoint3;
public ZFunRtsConfigJetty(int port) {
server = new Server();
connector = new ServerConnector(server);
connector.setPort(port);
server.addConnector(connector);
}
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
logger.info(" ╦┌─┐╔╦╗╔╦╗┬ ┬ ╔═╗┌─┐╦ ╦╔═╗┬─┐┌┬┐");
logger.info(" ║├┤ ║ ║ └┬┘ ╠═╝│ │║║║║╣ ├┬┘ ││");
logger.info("╚╝└─┘ ╩ ╩ ┴ ╩ └─┘╚╩╝╚═╝┴└──┴┘");
WebAppContext context = new WebAppContext();
context.setContextPath("/");
context.setBaseResource(buildBaseResource(getClass().getClassLoader()));
context.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/target/classes/|.*\\.jar");
context.setConfigurations(new Configuration[]{
//new AnnotationConfiguration(),
new WebInfConfiguration(),
});
server.setHandler(context);
JettyWebSocketServletContainerInitializer.configure(context, (servletContext, wsContainer) -> {
wsContainer.setMaxTextMessageSize(65535);
endpoint1 = new JettyWireServerEndpoint(wsContainer, "/con1");
endpoint2 = new JettyWireServerEndpoint(wsContainer, "/event");
endpoint3 = new JettyWireServerEndpoint(wsContainer, "/other");
});
logger.info("Add H2 console on: /debug/jdbc/console");
context.addServlet("org.h2.server.web.WebServlet", "/debug/jdbc/console/*");
context.addServlet(RedirectServlet.class, "/test");
// for static
ServletHolder staticHome = new ServletHolder("staticHome", DefaultServlet.class);
staticHome.setInitParameter("dirAllowed","false");
context.addServlet(staticHome, "/");
logger.info("Add request logger console");
CustomRequestLog log = new CustomRequestLog("logs/http.log", CustomRequestLog.EXTENDED_NCSA_FORMAT);
server.setRequestLog(log);
No2AllReact react = signal.getReact();
server.addEventListener(new Listener() {
@Override
public void lifeCycleStarted(LifeCycle event) {
react.fire(No2AllRtsServer.API, new No2AllActServer(endpoint1));
react.fire(No2AllRtsServer.API, new No2AllActServer(endpoint2));
react.fire(No2AllRtsServer.API, new No2AllActServer(endpoint3));
}
});
try {
logger.info("start jetty");
server.start();
logger.info("jetty started");
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
private Resource buildBaseResource(ClassLoader cl) {
try {
List<URL> paths = Collections.list(cl.getResources("META-INF/resources"));
Resource[] resources = new Resource[paths.size() + 1];
for (int i = 0; i < paths.size(); i++) {
resources[i] = Resource.newResource(paths.get(i));
}
resources[paths.size()] = Resource.newResource("target/classes/static");
return new ResourceCollection(resources);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
public void join() {
try {
server.join();
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
public void stop() {
try {
server.stop();
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
}

View file

@ -0,0 +1,44 @@
package love.distributedrebirth.no2all.zerofungus.service;
import java.util.logging.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.bridge.SLF4JBridgeHandler;
import ch.qos.logback.core.status.NopStatusListener;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
public class ZFunRtsConfigLogger implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(ZFunRtsConfigLogger.class);
private static final Logger logger = Logger.getLogger(ZFunRtsConfigLogger.class.getName());
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
if (System.getProperty("logback.configurationFile") == null) {
String logConfig = null;
if (System.getProperty("java.class.path").contains("classes")) {
logConfig = "conf/logback-server-console.xml";
} else {
logConfig = "conf/logback-server.xml";
}
System.setProperty("logback.configurationFile", logConfig);
}
if (System.getProperty("logback.statusListenerClass") == null) {
System.setProperty("logback.statusListenerClass",NopStatusListener.class.getName());
}
org.slf4j.Logger logger2 = LoggerFactory.getLogger(ZFunRtsConfigLogger.class);
logger2.info("Logging configured.");
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
logger.info(" ╦┬ ┬╦ ╦═╗┌─┐╦ ╦┬╦═╗┌─┐╔╦╗");
logger.info(" ║│ │║ ╠╦╝├┤ ║║║│╠╦╝├┤ ║║");
logger.info("╚╝└─┘╩═╝ ╩╚═└─┘╚╩╝┴╩╚═└─┘═╩╝");
//https://patorjk.com/software/taag
// Calvin S
}
}

View file

@ -0,0 +1,62 @@
package love.distributedrebirth.no2all.zerofungus.service;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Logger;
import javax.sql.DataSource;
import org.flywaydb.core.Flyway;
import org.h2.jdbcx.JdbcConnectionPool;
import love.distributedrebirth.no2all.react.No2AllReactSlot;
import love.distributedrebirth.no2all.react.No2AllReactSlotLoad;
import love.distributedrebirth.no2all.react.No2AllReactSlotSignal;
import love.distributedrebirth.no2all.react.No2AllReactTypeScript;
import love.distributedrebirth.no2all.react.warp.No2AllReactWarpCore;
public class ZFunRtsInitJdbc implements No2AllReactTypeScript {
public static final No2AllReactSlot API = No2AllReactSlot.ofClass(ZFunRtsInitJdbc.class);
private static final Logger logger = Logger.getLogger(ZFunRtsInitJdbc.class.getName());
private final No2AllReactWarpCore foei;
public ZFunRtsInitJdbc(No2AllReactWarpCore foei) {
this.foei = foei;
}
@Override
public void onEvent(No2AllReactSlotSignal<No2AllReactSlotLoad> signal) {
signal.getReact().claim(API);
JdbcConnectionPool cp = JdbcConnectionPool.create("jdbc:h2:file:./target/h2db/zfun", "sa", "sa");
foei.addService(JdbcConnectionPool.class, cp);
foei.addService(DataSource.class, cp);
Flyway flyway = Flyway.configure().schemas("ᔆʸᔆᐪᓫᔿ", "other", "ssd").table("ᣔᒃᣔᒼᓑᔆ").dataSource(cp).load();
flyway.migrate();
logger.info("╔╦╗┌─┐╔╦╗┌─┐╔╗ ┌─┐╔═╗┌─┐ ╔═╗┌─┐╔╦╗┬ ┬┌─┐");
logger.info(" ║║├─┤ ║ ├─┤╠╩╗├─┤╚═╗├┤ ╚═╗├┤ ║ │ │├─┘");
logger.info("═╩╝┴ ┴ ╩ ┴ ┴╚═╝┴ ┴╚═╝└─┘ ╚═╝└─┘ ╩ └─┘┴ ");
try {
startDone();
} catch (SQLException e) {
throw new IllegalStateException(e);
}
}
public void startDone() throws SQLException {
JdbcConnectionPool cp = foei.service(JdbcConnectionPool.class);
try (Connection conn = cp.getConnection()) {
String sql = "SELECT COUNT(\"ᑊᑊᐣ\") FROM \"ᔆʸᔆᐪᓫᔿ\".\"ᔆᐪᣔᒼᒽᑉ\"";
PreparedStatement prep = conn.prepareStatement(sql);
ResultSet rs = prep.executeQuery();
if (rs.first()) {
Long records = rs.getLong(1);
logger.info("DB Records: " + records + " from: " + sql);
}
}
}
}

View file

@ -0,0 +1,17 @@
package love.distributedrebirth.no2all.zerofungus.web;
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RedirectServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.sendRedirect("/powp/error/errmsg.html?title=NotHere&msg=TheEnd");
}
}

View file

@ -0,0 +1,37 @@
DROP TABLE IF EXISTS "ᒄᒃᓑᔆᓫᣗ";
CREATE TABLE IF NOT EXISTS "ᒄᒃᓑᔆᓫᣗ" (
"ᑊᑊᐣ" BIGINT NOT NULL AUTO_INCREMENT,
"ᣕᣔᔿᓫ" VARCHAR(100) NOT NULL,
"ᓑᔆᓫᣗᣕᣔᔿᓫ" VARCHAR(45) NOT NULL,
"ᣖᣔᔆᔆᒡᒢᐤᣗᒄ" VARCHAR(256) NOT NULL,
"ᓫᔿᣔᑊᒻ" VARCHAR(200) NOT NULL,
"ᔆᐪᣔᐪᓑᔆ" VARCHAR(45) NOT NULL,
delete_reason VARCHAR(500) NULL,
create_dt DATETIME NOT NULL DEFAULT now(),
create_uid BIGINT NOT NULL DEFAULT 1,
modify_dt DATE NULL,
modify_uid BIGINT NULL,
PRIMARY KEY ("ᑊᑊᐣ"))
;
CREATE UNIQUE INDEX "ᒄᒃᓑᔆᓫᣗᐨᓑᑊᐣᕁᐨᓑᔆᓫᣗᣕᣔᔿᓫ" ON "ᒄᒃᓑᔆᓫᣗ" ("ᓑᔆᓫᣗᣕᣔᔿᓫ" ASC);
CREATE INDEX "ᒄᒃᓑᔆᓫᣗᐨᑊᑊᐣᕁᐨᔆᐪᣔᐪᓑᔆ" ON "ᒄᒃᓑᔆᓫᣗ" ("ᔆᐪᣔᐪᓑᔆ" ASC);
CREATE TABLE IF NOT EXISTS "ᔆᐪᣔᒼᒽᑉ" (
"ᑊᑊᐣ" text NOT NULL,
"ᣖᓑᒃᒽᑉᓫᔾ" TEXT NOT NULL,
"ᒼᣗᓫᣔᐪᓫᐝᒄᐪ" DATETIME NOT NULL DEFAULT now(),
"ᑊᑉᑊᣕᒄ" INTEGER NOT NULL,
"ᒄᓫᒻᐪᣔᕐ" TEXT NULL,
"ᓫᕁᣖᑊᣗᓫᐝᒄᐪ" DATETIME NULL,
"ᣗᣔᒡᒢ" JSON NOT NULL,
PRIMARY KEY ("ᑊᑊᐣ"))
;
CREATE UNIQUE INDEX IF NOT EXISTS "ᔆᐪᣔᒼᒽᑉᐨᓑᑊᐣᕁᐨᑊᑊᐣ" ON "ᔆᐪᣔᒼᒽᑉ" USING btree ("ᑊᑊᐣ");
CREATE INDEX IF NOT EXISTS "ᔆᐪᣔᒼᒽᑉᐨᑊᑊᐣᕁᐨᣖᓑᒃᒽᑉᓫᔾ" ON "ᔆᐪᣔᒼᒽᑉ" USING btree ("ᣖᓑᒃᒽᑉᓫᔾ");
CREATE INDEX IF NOT EXISTS "ᔆᐪᣔᒼᒽᑉᐨᑊᑊᐣᕁᐨᒼᣗᓫᣔᐪᓫᐝᒄᐪ" ON "ᔆᐪᣔᒼᒽᑉ" ("ᒼᣗᓫᣔᐪᓫᐝᒄᐪ" DESC);
CREATE INDEX IF NOT EXISTS "ᔆᐪᣔᒼᒽᑉᐨᑊᑊᐣᕁᐨᑊᑉᑊᣕᒄ" ON "ᔆᐪᣔᒼᒽᑉ" ("ᑊᑉᑊᣕᒄ");
CREATE INDEX IF NOT EXISTS "ᔆᐪᣔᒼᒽᑉᐨᑊᑊᐣᕁᐨᓫᕁᣖᑊᣗᓫᐝᒄᐪ" ON "ᔆᐪᣔᒼᒽᑉ" ("ᓫᕁᣖᑊᣗᓫᐝᒄᐪ" DESC);

View file

@ -0,0 +1,3 @@
INSERT INTO "ᒄᒃᓑᔆᓫᣗ" ("ᑊᑊᐣ", "ᣕᣔᔿᓫ", "ᓑᔆᓫᣗᣕᣔᔿᓫ", "ᣖᣔᔆᔆᒡᒢᐤᣗᒄ", "ᓫᔿᣔᑊᒻ", "ᔆᐪᣔᐪᓑᔆ") VALUES (1, 'Technical User', 'tech', '00000000', 'technical@', 'TECHNICAL');
INSERT INTO "ᒄᒃᓑᔆᓫᣗ" ("ᑊᑊᐣ", "ᣕᣔᔿᓫ", "ᓑᔆᓫᣗᣕᣔᔿᓫ", "ᣖᣔᔆᔆᒡᒢᐤᣗᒄ", "ᓫᔿᣔᑊᒻ", "ᔆᐪᣔᐪᓑᔆ") VALUES (2, 'Admin', 'admin', '000000000', 'admin@', 'ACTIVE');

View file

@ -0,0 +1,36 @@
-- Test case for H2 webconsole unicode autocomplete escaping and quoting.
-- http://localhost:8080/debug/jdbc/console
CREATE SCHEMA "Господь мой пастырь";
CREATE TABLE "Господь мой пастырь"."Я не захочу." (
"Он заставляет меня лечь" BIGINT NOT NULL AUTO_INCREMENT,
"на зеленых пастбищах" VARCHAR(500) NULL,
"Он ведет меня" DATETIME NOT NULL DEFAULT now(),
"возле стоячей воды" BIGINT NOT NULL DEFAULT 1,
PRIMARY KEY ("Он заставляет меня лечь"))
;
CREATE TABLE "Господь мой пастырь"."Он восстанавливает мою душу." (
"Он ведет меня путями" BIGINT NOT NULL AUTO_INCREMENT,
"праведности" VARCHAR(500) NULL,
"ради его имени" DATETIME NOT NULL DEFAULT now(),
PRIMARY KEY ("Он ведет меня путями"))
;
CREATE SCHEMA "Хотя я иду по долине";
CREATE TABLE "Хотя я иду по долине"."тени смерти" (
"Я не буду бояться зла" BIGINT NOT NULL AUTO_INCREMENT,
"ибо ты со мной;" VARCHAR(500) NULL,
"твой жезл и твой посох," DATETIME NOT NULL DEFAULT now(),
"они меня утешают." BIGINT NOT NULL DEFAULT 1,
PRIMARY KEY ("Я не буду бояться зла"))
;
CREATE INDEX "Ты готовишь стол раньше меня" ON "Хотя я иду по долине"."тени смерти" ("ибо ты со мной;" ASC);
CREATE INDEX "в присутствии моих врагов;" ON "Хотя я иду по долине"."тени смерти" ("твой жезл и твой посох," ASC);
CREATE TABLE "Хотя я иду по долине"."Ты помажешь мне голову маслом;" (
"мой запас переполнен." BIGINT NOT NULL AUTO_INCREMENT,
"Воистину, добро и милосердие последуют за мной." VARCHAR(100) NULL,
"все дни моей жизни," VARCHAR(200) NULL,
"и буду жить в доме Господнем" VARCHAR(300) NULL,
"навсегда." VARCHAR(400) NULL,
PRIMARY KEY ("мой запас переполнен."))
;

View file

@ -0,0 +1,35 @@
* {
margin: 0;
padding: 0;
}
body {
font-family: "Helvetica Neue", "Helvetica", "Arial";
font-size: 14px;
background-color: rgba(45, 67, 49, 0.32);
}
.container {
width: 500px;
margin: 25px auto;
padding-top: 25px;
}
.dialog {
padding: 20px;
background-color: #233927;
color: #fff;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
margin-top: 25px;
}
form .dialog, #errorTitle {
color: #ff0000;
}
.hidden {
display: none;
}

View file

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Error</title>
<meta name="keywords" content="error">
<meta name="description" content="Error">
<script src="../../webjars/jquery/3.5.1/jquery.slim.min.js"></script>
<link rel="stylesheet" href="errmsg.css">
</head>
<body>
<div class="container">
<div class="dialog">
<h2 id="errorTitle">Error</h2>
<p><br></p>
<p>We could not process your request because;</p>
<p id="errorMessage">...</p>
<a href="/">Home</a>
</div>
</div>
<script>
"use strict";
(function($) {
var searchParams = new URLSearchParams(window.location.search);
if (searchParams.has('msg')) {
$('#errorMessage').html(searchParams.get('msg').replace(/_/g, ' '));
}
if (searchParams.has('title')) {
var title = searchParams.get('title').replace(/_/g, ' ');
$('#errorTitle').html('Error || ' + title);
window.document.title = 'Error || ' + title;
}
})(jQuery);
</script>
</body>
</html>