Исправил что бы во входящих запросах тоже был  payload
This commit is contained in:
AidarKC 2025-12-09 18:34:17 +03:00
parent 199769cac0
commit 2b5fa16824
8 changed files with 97 additions and 37 deletions

View File

@ -17,12 +17,13 @@ import java.util.Map;
/** /**
* JsonInboundProcessor обработка JSON-сообщений. * JsonInboundProcessor обработка JSON-сообщений.
*. *
* 1) Парсит общий пакет (op, requestId,...). * 1) Парсит общий пакет (op, requestId, payload).
* 2) По op выбирает класс запроса и хэндлер. * 2) По op выбирает класс запроса и хэндлер.
* 3) Маппит JSON NetRequest через ObjectMapper. * 3) Собирает "плоский" объект: op + requestId + поля из payload.
* 4) Вызывает хэндлер, получает NetResponse. * 4) Маппит его в NetRequest через ObjectMapper.
* 5) Собирает JSON-ответ: * 5) Вызывает хэндлер, получает NetResponse.
* 6) Собирает JSON-ответ:
* { * {
* "op": ..., * "op": ...,
* "requestId": ..., * "requestId": ...,
@ -42,7 +43,9 @@ public final class JsonInboundProcessor {
private static final Map<String, Class<? extends NetRequest>> JSON_REQUEST_TYPES = private static final Map<String, Class<? extends NetRequest>> JSON_REQUEST_TYPES =
JsonHandlerRegistry.getRequestTypes(); JsonHandlerRegistry.getRequestTypes();
private JsonInboundProcessor() {} private JsonInboundProcessor() {
// utility
}
public static String processJson(String json, ConnectionContext ctx) { public static String processJson(String json, ConnectionContext ctx) {
String op = null; String op = null;
@ -63,7 +66,7 @@ public final class JsonInboundProcessor {
// 1. Парсим общий пакет // 1. Парсим общий пакет
JsonNode root = JSON_MAPPER.readTree(json); JsonNode root = JSON_MAPPER.readTree(json);
// 2. op и requestId // 2. op и requestId из корня
op = getTextOrNull(root, "op"); op = getTextOrNull(root, "op");
requestId = getTextOrNull(root, "requestId"); requestId = getTextOrNull(root, "requestId");
@ -92,12 +95,50 @@ public final class JsonInboundProcessor {
return writeResponse(err); return writeResponse(err);
} }
// 3. Маппим JSON нужный NetRequest // 3. Берём payload
NetRequest request = JSON_MAPPER.treeToValue(root, reqClass); JsonNode payloadNode = root.get("payload");
if (payloadNode == null || payloadNode.isNull()) {
NetExceptionResponse err = NetExceptionResponseFactory.error(
op,
requestId,
WireCodes.Status.BAD_REQUEST,
"NO_PAYLOAD",
"Поле 'payload' отсутствует"
);
return writeResponse(err);
}
if (!payloadNode.isObject()) {
NetExceptionResponse err = NetExceptionResponseFactory.error(
op,
requestId,
WireCodes.Status.BAD_REQUEST,
"BAD_PAYLOAD",
"Поле 'payload' должно быть объектом"
);
return writeResponse(err);
}
// 3.1 Собираем "плоский" объект для маппинга в NetRequest:
// op + requestId + поля из payload
ObjectNode merged = JSON_MAPPER.createObjectNode();
// Добавляем op и requestId, чтобы они попали в NetRequest
if (op != null) {
merged.put("op", op);
}
if (requestId != null) {
merged.put("requestId", requestId);
}
// Добавляем все поля из payload внутрь
merged.setAll((ObjectNode) payloadNode);
// 4. Маппим в конкретный класс NetRequest
NetRequest request = JSON_MAPPER.treeToValue(merged, reqClass);
NetResponse response; NetResponse response;
// 4. Трай-кэтч вокруг хэндлера // 5. Вызываем хэндлер
try { try {
response = handler.handle(request, ctx); response = handler.handle(request, ctx);
} catch (Exception handlerError) { } catch (Exception handlerError) {
@ -116,7 +157,7 @@ public final class JsonInboundProcessor {
if (response.getOp() == null) response.setOp(op); if (response.getOp() == null) response.setOp(op);
if (response.getRequestId() == null) response.setRequestId(requestId); if (response.getRequestId() == null) response.setRequestId(requestId);
// 5. Универсальная сборка ответа // 6. Универсальная сборка ответа
return writeResponse(response); return writeResponse(response);
} catch (Exception e) { } catch (Exception e) {

View File

@ -166,6 +166,7 @@ public class NetAuthSessionNewStep2Handler implements JsonMessageHandler {
ctx.setSessionId(sessionId); ctx.setSessionId(sessionId);
ctx.setAuthenticationStatus(ConnectionContext.AUTH_STATUS_USER); ctx.setAuthenticationStatus(ConnectionContext.AUTH_STATUS_USER);
ActiveConnectionsRegistry.getInstance().removeBySessionId(sessionId); // га всякий случай предварительно удаляем что бы точно небыло дублирования активной сессии
// Регистрируем это подключение в глобальном реестре активных соединений // Регистрируем это подключение в глобальном реестре активных соединений
ActiveConnectionsRegistry.getInstance().register(ctx); ActiveConnectionsRegistry.getInstance().register(ctx);

View File

@ -110,6 +110,7 @@ public class NetSessionRefreshHandler implements JsonMessageHandler {
ctx.setSessionPwd(sessionPwd); ctx.setSessionPwd(sessionPwd);
ctx.setAuthenticationStatus(ConnectionContext.AUTH_STATUS_USER); ctx.setAuthenticationStatus(ConnectionContext.AUTH_STATUS_USER);
ActiveConnectionsRegistry.getInstance().removeBySessionId(sessionId); // на всякий случай удаляем что бы точно небыло повторов
// Регистрируем это подключение в глобальном реестре активных соединений // Регистрируем это подключение в глобальном реестре активных соединений
ActiveConnectionsRegistry.getInstance().register(ctx); ActiveConnectionsRegistry.getInstance().register(ctx);
} }

1
src/TODO.txt Normal file
View File

@ -0,0 +1 @@
Сделать потом что бы на каждую сессию стояло время последнего подключения и откуда оно было - но видимо это уже в свойства запихивать надо.

View File

@ -16,8 +16,10 @@ public class TestJsonWsClient2 {
{ {
"op": "SessionRefresh", "op": "SessionRefresh",
"requestId": "test-1", "requestId": "test-1",
"sessionId": 123, "payload": {
"sessionPwd": "test-password" "sessionId": 123,
"sessionPwd": "test-password"
}
} }
"""; """;
@ -25,12 +27,14 @@ public class TestJsonWsClient2 {
{ {
"op": "AddUser", "op": "AddUser",
"requestId": "test-add-1", "requestId": "test-add-1",
"login": "anya1111", "payload": {
"loginId": 100211, "login": "anya1111",
"bchId": 4222, "loginId": 100211,
"pubkey0": "PUB0", "bchId": 4222,
"pubkey1": "PUB1", "pubkey0": "PUB0",
"bchLimit": 1000000 "pubkey1": "PUB1",
"bchLimit": 1000000
}
} }
"""; """;
@ -38,7 +42,9 @@ public class TestJsonWsClient2 {
{ {
"op": "AuthSessionNewStep1", "op": "AuthSessionNewStep1",
"requestId": "test-auth-1", "requestId": "test-auth-1",
"login": "anya1111" "payload": {
"login": "anya1111"
}
} }
"""; """;

View File

@ -64,12 +64,14 @@ public class Test_AddUser_FirstAuth {
{ {
"op": "AddUser", "op": "AddUser",
"requestId": "test-add-1", "requestId": "test-add-1",
"login": "%s", "payload": {
"loginId": %d, "login": "%s",
"bchId": %d, "loginId": %d,
"pubkey0": "%s", "bchId": %d,
"pubkey1": "%s", "pubkey0": "%s",
"bchLimit": %d "pubkey1": "%s",
"bchLimit": %d
}
} }
""".formatted( """.formatted(
TEST_LOGIN, TEST_LOGIN,
@ -87,7 +89,9 @@ public class Test_AddUser_FirstAuth {
{ {
"op": "AuthSessionNewStep1", "op": "AuthSessionNewStep1",
"requestId": "test-auth-1", "requestId": "test-auth-1",
"login": "%s" "payload": {
"login": "%s"
}
} }
""".formatted(TEST_LOGIN); """.formatted(TEST_LOGIN);
} }
@ -112,10 +116,12 @@ public class Test_AddUser_FirstAuth {
{ {
"op": "AuthSessionNewStep2", "op": "AuthSessionNewStep2",
"requestId": "test-auth-2", "requestId": "test-auth-2",
"loginId": %d, "payload": {
"sigNum": 0, "loginId": %d,
"timeMs": %d, "sigNum": 0,
"signatureB64": "%s" "timeMs": %d,
"signatureB64": "%s"
}
} }
""".formatted( """.formatted(
TEST_LOGIN_ID, TEST_LOGIN_ID,

View File

@ -40,8 +40,10 @@ public class Test_SessionRefreshClient {
{ {
"op": "SessionRefresh", "op": "SessionRefresh",
"requestId": "test-session-refresh-1", "requestId": "test-session-refresh-1",
"sessionId": %d, "payload": {
"sessionPwd": "%s" "sessionId": %d,
"sessionPwd": "%s"
}
} }
""".formatted(SESSION_ID, SESSION_PWD); """.formatted(SESSION_ID, SESSION_PWD);
} }
@ -49,7 +51,6 @@ public class Test_SessionRefreshClient {
private static class ClientListener implements Listener { private static class ClientListener implements Listener {
private final CountDownLatch latch; private final CountDownLatch latch;
private boolean sent = false;
ClientListener(CountDownLatch latch) { ClientListener(CountDownLatch latch) {
this.latch = latch; this.latch = latch;
@ -67,7 +68,6 @@ public class Test_SessionRefreshClient {
System.out.println("📤 Отправляем SessionRefresh:"); System.out.println("📤 Отправляем SessionRefresh:");
System.out.println(json); System.out.println(json);
webSocket.sendText(json, true); webSocket.sendText(json, true);
sent = true;
Listener.super.onOpen(webSocket); Listener.super.onOpen(webSocket);
} }

View File

@ -21,11 +21,15 @@ public final class WsServer {
AppConfig config = AppConfig.getInstance(); AppConfig config = AppConfig.getInstance();
int port = 7070; int port = 7070;
try { try {
port = Integer.parseInt(config.getParam("server.port"),7070); String portStr = config.getParam("server.port");
if (portStr != null && !portStr.isBlank()) {
port = Integer.parseInt(portStr.trim());
}
} catch (Exception e) { } catch (Exception e) {
log.info("Установите параметр server.port в файле настроек"); log.info("Не удалось прочитать параметр server.port, используем порт по умолчанию {}", port);
} }
Server server = new Server(port); Server server = new Server(port);
ServletContextHandler context = new ServletContextHandler(); ServletContextHandler context = new ServletContextHandler();