I'm developing an architecture with multiple users communicating with each other via server (Glassfish).
Inspiration for this was: http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/HomeWebsocket/WebsocketHome.html
The problem I face is large class. What I would like to achieve is to divide ClientSessionHandler
class into classes responsible for:
logging into system
data exchanging between client-server-master client
Here is the code:
ClientSessionHandler.java
@ApplicationScoped
public class ClientSessionHandler {
private final Map<Session, Integer> sessions = new HashMap<>(); // sesja +
// ID
private final Map<Integer, Integer> clients = new HashMap<>(); // ID + state
private Session masterClientSession = null;
private AppOneData appOneData = new AppOneData();
private AppTwoData appTwoData = new AppTwoData();
private AppThreeData appThreeData = new AppThreeData();
private AppFourData appFourData = new AppFourData();
public ClientSessionHandler() {
for (int i = 1; i <= 6; i++) {
clients.put(i, 0);
}
}
/* LOGGING */
/*********/
// add client to data structures
public void sendIdToClient(Integer clientID, Session session) {
JsonProvider provider = JsonProvider.provider();
JsonObject idMessage = provider.createObjectBuilder().add("action", "idDeclared").build();
sessions.put(session, clientID);
clients.put(clientID, Strings.LOGGED_IN);
sendToSession(session, idMessage);
// send to master-client aswell
if (masterClientSession != null) {
sendClientsStateToMasterClient(masterClientSession);
}
}
// remove client from data structures
public void removeClient(Session session) {
int clientID = sessions.remove(session);
clients.put(clientID, Strings.LOGGED_OUT);
if (masterClientSession != null) {
sendClientsStateToMasterClient(masterClientSession);
}
}
public void saveMasterClientSession(Session session) {
masterClientSession = session;
}
// after master-client log-in
public void sendClientsStateToMasterClient(Session session) {
JsonProvider provider = JsonProvider.provider();
JsonObjectBuilder builder = provider.createObjectBuilder().add("action", "changedState");
for (int i = 1; i <= clients.size(); i++) {
builder.add("client" + i, (int) clients.get(i));
}
JsonObject idMessage = builder.build();
sendToSession(session, idMessage);
}
// after change on client side
public void sendClientStateToMasterClient(int clientID, int clientState) {
clients.put(clientID, clientState);
if (masterClientSession != null) {
sendClientsStateToMasterClient(masterClientSession);
}
}
// response to client state change sent by master-client
public void sendMessageToClient(int clientID, int clientState, String task) {
clients.put(clientID, clientState);
Session clientSession = CollectionManager.getSessionFromID(sessions, clientID);
if (clientSession != null) {
JsonProvider provider = JsonProvider.provider();
JsonObject idMessage = provider.createObjectBuilder().add("action", task).build();
sendToSession(clientSession, idMessage);
}
}
private void sendToSession(Session session, JsonObject message) {
try {
session.getBasicRemote().sendText(message.toString());
} catch (IOException ex) {
sessions.remove(session);
Logger.getLogger(ClientSessionHandler.class.getName()).log(Level.SEVERE, null, ex);
}
}
// data from app1
public void sendDataToMasterClient(int clientID, String controlName, boolean controlValue) {
createAndSendUpdatingJson(controlName, controlValue, masterClientSession);
}
// data from master-client to app1
public void sendDataToClient(int clientID, String controlName, boolean controlValue) {
Session clientSession = CollectionManager.getSessionFromID(sessions, clientID);
createAndSendUpdatingJson(controlName, controlValue, clientSession);
}
// for the use of app1 both client and master-client
private void createAndSendUpdatingJson(String controlName, boolean controlValue, Session session) {
JsonProvider provider = JsonProvider.provider();
JsonObject idMessage = provider.createObjectBuilder().add("action", "toggle-element")
.add("controlName", controlName).add("controlValue", controlValue).build();
sendToSession(session, idMessage);
}
public void saveDataOnServer(int clientID, String controlName, boolean controlValue) {
if (clientID == Strings.APPLICATION_ONE) {
switch (controlName) {
case Strings.APP_ONE_VALVE_1:
appOneData.setValve1(controlValue);
break;
case Strings.APP_ONE_VALVE_2:
appOneData.setValve2(controlValue);
break;
case Strings.APP_ONE_MOTOR_3:
appOneData.setMotorA(controlValue);
appOneData.setMotorB(!controlValue);
break;
case Strings.APP_ONE_MOTOR_4:
appOneData.setMotorA(controlValue);
appOneData.setMotorB(!controlValue);
break;
case Strings.APP_ONE_CHECKBOX_5:
appOneData.setExhaust(controlValue);
break;
case Strings.APP_ONE_CHECKBOX_6:
appOneData.setFilter(controlValue);
break;
}
sendDataToMasterClient(clientID, controlName, controlValue);
sendDataToClient(clientID, controlName, controlValue);
}
}
// data from app2&3
public void sendDataToMasterClient(int clientID, String controlName, double controlValue, String output) {
createAndSendUpdatingJson(controlName, controlValue, masterClientSession, output);
}
// data from master-client to app2&app3
public void sendDataToClient(int clientID, String controlName, double controlValue, String output) {
Session clientSession = CollectionManager.getSessionFromID(sessions, clientID);
createAndSendUpdatingJson(controlName, controlValue, clientSession, output);
}
// for the use of app2&3 both client and master-client
private void createAndSendUpdatingJson(String controlName, double controlValue, Session session, String output) {
JsonProvider provider = JsonProvider.provider();
JsonObject idMessage = provider.createObjectBuilder().add("action", "set-element-value")
.add("controlName", controlName).add("controlValue", controlValue).add("outputName", output).build();
sendToSession(session, idMessage);
}
public void saveDataOnServer(int clientID, String controlName, double controlValue, String output) {
if (clientID == Strings.APPLICATION_TWO) {
switch (controlName) {
case Strings.APP_TWO_VELOCITY:
appTwoData.setVelocityInput(controlValue);
break;
case Strings.APP_TWO_PRESSURE:
appTwoData.setPressureInput(controlValue);
break;
}
}
if (clientID == Strings.APPLICATION_THREE) {
switch (controlName) {
case Strings.APP_THREE_VOLTAGE_1:
appThreeData.setVoltage1(controlValue);
break;
case Strings.APP_THREE_VOLTAGE_2:
appThreeData.setVoltage2(controlValue);
break;
}
}
sendDataToMasterClient(clientID, controlName, controlValue, output);
sendDataToClient(clientID, controlName, controlValue, output);
}
public void generateNumbers(int clientID) {
appFourData.setFirstTurn(RandomNumberGenerator.generateNumber(60));
appFourData.setSecondTurn(RandomNumberGenerator.generateNumber(60));
appFourData.setThirdTurn(RandomNumberGenerator.generateNumber(60));
//TODO:
}
}
And I present websocket class if someone finds it necessary:
@ApplicationScoped
@ServerEndpoint("/actions")
public class ClientsWebSocketServer {
@Inject
private ClientSessionHandler sessionHandler;
@OnOpen
public void open(Session session) {
}
@OnClose
public void close(Session session) {
sessionHandler.removeClient(session);
}
@OnError
public void onError(Throwable error) {
}
@OnMessage
public void handleMessage(String message, Session session) {
System.out.println(message+session);
try(JsonReader reader = Json.createReader(new StringReader(message))) {
JsonObject jsonMessage = reader.readObject();
if("get-id".equals(jsonMessage.getString("action"))) {
int clientID = jsonMessage.getInt("id");
sessionHandler.sendIdToClient(clientID,session);
}
if("get-master-id".equals(jsonMessage.getString("action"))) {
sessionHandler.saveMasterClientSession(session);
sessionHandler.sendClientsStateToMasterClient(session);
}
if("client-ready".equals(jsonMessage.getString("action"))) {
int clientID = jsonMessage.getInt("id");
sessionHandler.sendClientStateToMasterClient(clientID, Strings.START_BUTTON_NOTIFICATION);
}
if("client-stop".equals(jsonMessage.getString("action"))) {
int clientID = jsonMessage.getInt("id");
sessionHandler.sendClientStateToMasterClient(clientID, Strings.LOGGED_IN);
}
if("allow-user".equals(jsonMessage.getString("action"))) {
int clientID = jsonMessage.getInt("id");
sessionHandler.sendMessageToClient(clientID, Strings.MASTER_CLIENT_APPROVAL, "permitOperating");
}
if("stop-user".equals(jsonMessage.getString("action"))) {
int clientID = jsonMessage.getInt("id");
sessionHandler.sendMessageToClient(clientID, Strings.LOGGED_IN, "prohibitOperating");
}
if("toggle-element".equals(jsonMessage.getString("action"))) {
int clientID = jsonMessage.getInt("id");
String name = jsonMessage.getString("name");
boolean value = jsonMessage.getBoolean("value");
sessionHandler.saveDataOnServer(clientID, name, value);
}
if("set-element-value".equals(jsonMessage.getString("action"))) {
int clientID = jsonMessage.getInt("id");
String name = jsonMessage.getString("name");
double value = Double.parseDouble(jsonMessage.getString("value"));
String output = jsonMessage.getString("output");
sessionHandler.saveDataOnServer(clientID, name, value, output);
}
if("generate-number".equals(jsonMessage.getString("action"))) {
int clientID = jsonMessage.getInt("id");
sessionHandler.generateNumbers(clientID);
}
}
}
}