use of org.structr.websocket.command.PingCommand in project structr by structr.
the class StructrWebSocket method onWebSocketText.
@Override
public void onWebSocketText(final String data) {
if (!Services.getInstance().isInitialized()) {
// send 401 Authentication Required
send(MessageBuilder.status().code(503).message("System is not initialized yet").build(), true);
}
final Services servicesInstance = Services.getInstance();
// wait for service layer to be initialized
while (!servicesInstance.isInitialized()) {
try {
Thread.sleep(1000);
} catch (InterruptedException iex) {
}
}
if (data == null) {
logger.warn("Empty text message received.");
return;
}
logger.debug("############################################################ RECEIVED \n{}", data.substring(0, Math.min(data.length(), 1000)));
// parse web socket data from JSON
final WebSocketMessage webSocketData = gson.fromJson(data, WebSocketMessage.class);
final App app = StructrApp.getInstance(securityContext);
final String command = webSocketData.getCommand();
final Class type = commandSet.get(command);
final String sessionIdFromMessage = webSocketData.getSessionId();
if (type != null) {
try (final Tx tx = app.tx()) {
if (sessionIdFromMessage != null) {
// try to authenticated this connection by sessionId
authenticate(SessionHelper.getShortSessionId(sessionIdFromMessage), command.equals("PING"));
}
// we only permit LOGIN commands if authentication based on sessionId was not successful
if (!isAuthenticated() && !type.equals(LoginCommand.class)) {
// send 401 Authentication Required
send(MessageBuilder.status().code(401).message("").build(), true);
tx.success();
return;
}
tx.success();
} catch (DatabaseServiceNotAvailableException dbsnae) {
logger.warn(dbsnae.getMessage());
} catch (FrameworkException t) {
logger.warn("Unable to parse message.", t);
}
// process message
try {
AbstractCommand abstractCommand = (AbstractCommand) type.newInstance();
abstractCommand.setWebSocket(this);
abstractCommand.setSession(session);
abstractCommand.setCallback(webSocketData.getCallback());
if (!(abstractCommand instanceof PingCommand)) {
if (securityContext != null) {
final HttpSession session = SessionHelper.getSessionBySessionId(securityContext.getSessionId());
if (session != null) {
session.setMaxInactiveInterval(Services.getGlobalSessionTimeout());
try {
// Workaround to update lastAccessedTime() in Jetty's session via reflection
final Method accessMethod = ((org.eclipse.jetty.server.session.Session) session).getClass().getDeclaredMethod("access", long.class);
accessMethod.setAccessible(true);
accessMethod.invoke((org.eclipse.jetty.server.session.Session) session, System.currentTimeMillis());
} catch (Exception ex) {
logger.error("Access to method Session.access() via reflection failed: ", ex);
}
}
}
}
// transactions in case of bulk processing commands etc.
if (abstractCommand.requiresEnclosingTransaction()) {
try (final Tx tx = app.tx()) {
// store authenticated-Flag in webSocketData
// so the command can access it
webSocketData.setSessionValid(isAuthenticated());
abstractCommand.processMessage(webSocketData);
// commit transaction
tx.success();
}
} else {
try (final Tx tx = app.tx()) {
// store authenticated-Flag in webSocketData
// so the command can access it
webSocketData.setSessionValid(isAuthenticated());
// commit transaction
tx.success();
}
// process message without transaction context!
abstractCommand.processMessage(webSocketData);
}
} catch (FrameworkException | InstantiationException | IllegalAccessException t) {
try (final Tx tx = app.tx()) {
// send 400 Bad Request
if (t instanceof FrameworkException) {
final FrameworkException fex = (FrameworkException) t;
send(MessageBuilder.status().code(fex.getStatus()).message(fex.toString()).jsonErrorObject(fex.toJSON()).callback(webSocketData.getCallback()).build(), true);
} else {
send(MessageBuilder.status().code(400).message(t.toString()).build(), true);
}
// commit transaction
tx.success();
} catch (FrameworkException fex) {
logger.warn("Unable to send websocket result: {}", fex.getMessage());
}
return;
}
} else {
logger.warn("Unknown command {}", command);
// send 400 Bad Request
send(MessageBuilder.status().code(400).message("Unknown command").build(), true);
return;
}
}
Aggregations