Anonymous
Как решить большой переключатель в обработчике WebSocket в Java Spring
Сообщение
Anonymous » 26 окт 2024, 15:31
вот у меня есть обработчик WebSocket, он содержит огромный переключатель для обработки входящих запросов, как решить эту проблему
Код: Выделить всё
@RequiredArgsConstructor
@Component
public class EditorOperationsWebSocketHandler extends TextWebSocketHandler {
private final MessageParser messageParser;
private final ProjectService projectService;
private final FolderService folderService;
private final FileService fileService;
private final CommentService commentService;
private final DiscussionService discussionService;
private final ConcurrentHashMap projectSessions = new ConcurrentHashMap();
private final ConcurrentHashMap discussionSessions = new ConcurrentHashMap();
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
String username = (String) session.getAttributes().get("sub");
Integer projectId = (Integer) session.getAttributes().get("projectId");
if (username != null && projectId != null) {
projectSessions.computeIfAbsent(projectId, k -> new ConcurrentLinkedQueue()).add(session);
System.out.println("Session added for project ID: " + projectId + " with user: " + username);
} else {
session.close(CloseStatus.NOT_ACCEPTABLE);
}
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
String payload = message.getPayload();
System.out.println("Received message: " + payload);
handleMessage(session, payload);
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
//cleanup(session);
}
public void handleMessage(WebSocketSession session, String jsonMessage) {
try {
Message message = messageParser.parseMessage(jsonMessage);
System.out.println(message.getData());
Integer projectId = (Integer) session.getAttributes().get("projectId");
Integer userId = (Integer) session.getAttributes().get("userId");
switch (message.getAction()) {
case "create-file":
Message createFileDTOMessage = messageParser.parseMessage(jsonMessage, CreateFileDTO.class);
var file = fileService.createFileByUser(createFileDTOMessage.getData(), userId);
broadcastMessageToProjectMembers(projectId, new Message("get-project-structure", projectService.getFolderTree(projectId)));
break;
case "delete-file":
Message deleteFileDTOMessage = messageParser.parseMessage(jsonMessage, Integer.class);
fileService.deleteFile(deleteFileDTOMessage.getData());
broadcastMessageToProjectMembers(projectId, new Message("get-project-structure", projectService.getFolderTree(projectId)));
break;
case "create-folder":
Message createFolderDTOMessage = messageParser.parseMessage(jsonMessage, CreateFolderDTO.class);
var folder = folderService.createFolder(createFolderDTOMessage.getData());
broadcastMessageToProjectMembers(projectId, new Message("get-project-structure", projectService.getFolderTree(projectId)));
break;
case "create-primary-folder":
Message createPrimaryFolderDTOMessage = messageParser.parseMessage(jsonMessage, CreatePrimaryFolderDTO.class);
var primaryFolder = folderService.createPrimaryFolder(createPrimaryFolderDTOMessage.getData());
broadcastMessageToProjectMembers(projectId, new Message("get-project-structure", projectService.getFolderTree(projectId)));
break;
case "delete-folder":
Message deleteFolderDTO = messageParser.parseMessage(jsonMessage, Integer.class);
folderService.delete(deleteFolderDTO.getData());
broadcastMessageToProjectMembers(projectId, new Message("get-project-structure", projectService.getFolderTree(projectId)));
break;
case "edit-file":
Message updateFileDTO = messageParser.parseMessage(jsonMessage, UpdateFileDTO.class);
fileService.editFileByUser(updateFileDTO.getData(), userId);
var readFileDTO = new ReadFileDTO(fileService.getFileById(updateFileDTO.getData().fileId()), updateFileDTO.getData().fileId());
broadcastMessageToProjectMembersExceptSender(session, projectId, new Message("get-file-content", readFileDTO));
break;
case "create-comment":
Message createCommentDTOMessage = messageParser.parseMessage(jsonMessage, CreateCommentDTO.class);
var savedComment= commentService.createComment(createCommentDTOMessage.getData());
broadcastMessageToDiscussionMembers(createCommentDTOMessage.getData().discussionId(), new Message("get-comment", savedComment));
break;
case "create-discussion":
Message createDiscussionDTOMessage = messageParser.parseMessage(jsonMessage, CreateDiscussionDTO.class);
var savedDiscussion=discussionService.createDiscussion(createDiscussionDTOMessage.getData());
broadcastMessageToProjectMembers(projectId,new Message("get-discussion", savedDiscussion));
break;
case "join-discussion":
Message joinDiscussionDTOMessage = messageParser.parseMessage(jsonMessage, JoinDiscussionDTO.class);
discussionSessions.computeIfAbsent(joinDiscussionDTOMessage.getData().discussionId(), k -> new ConcurrentLinkedQueue()).add(session);
sendMessage(session, new Message("join-discussion-done","join discussion done"));
break;
case "exit-discussion":
Message exitDiscussionDTOMessage = messageParser.parseMessage(jsonMessage, JoinDiscussionDTO.class);
discussionSessions.get(exitDiscussionDTOMessage.getData().discussionId()).remove(session);
sendMessage(session, new Message("exit-discussion-done","exit discussion done"));
break;
case "project-structure":
sendMessage(session, new Message("get-project-structure", projectService.getFolderTree(projectId)));
break;
default:
//System.out.println("Unknown action: " + executionMessage.getAction());
break;
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void broadcastMessageToProjectMembers(Integer projectId, Message messageContent) {
ConcurrentLinkedQueue sessions = projectSessions.get(projectId);
broadcastMessageToMembers(sessions, messageContent);
}
private void broadcastMessageToDiscussionMembers(Integer discussionId, Message messageContent) {
ConcurrentLinkedQueue sessions = discussionSessions.get(discussionId);
broadcastMessageToMembers(sessions, messageContent);
}
private void broadcastMessageToMembers(ConcurrentLinkedQueue sessions, Message messageContent) {
if (sessions != null) {
try {
TextMessage message = new TextMessage(messageParser.parseMessage(messageContent));
for (WebSocketSession session : sessions) {
if (session.isOpen()) {
session.sendMessage(message);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void broadcastMessageExceptSender(ConcurrentLinkedQueue sessions, WebSocketSession senderSession, Message messageContent) {
if (sessions != null) {
try {
String jsonMessage = messageParser.parseMessage(messageContent);
TextMessage message = new TextMessage(jsonMessage);
for (WebSocketSession session : sessions) {
if (session.isOpen() && !session.getId().equals(senderSession.getId())) {
session.sendMessage(message);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void broadcastMessageToDiscussionMembersExceptSender(WebSocketSession senderSession, Integer discussionId, Message messageContent) {
ConcurrentLinkedQueue sessions = discussionSessions.get(discussionId);
broadcastMessageExceptSender(sessions, senderSession, messageContent);
}
private void broadcastMessageToProjectMembersExceptSender(WebSocketSession senderSession, Integer projectId, Message messageContent) {
ConcurrentLinkedQueue sessions = projectSessions.get(projectId);
broadcastMessageExceptSender(sessions, senderSession, messageContent);
}
private void sendMessage(WebSocketSession session, Message message) {
if (session.isOpen()) {
try {
String jsonMessage = messageParser.parseMessage(message);
session.sendMessage(new TextMessage(jsonMessage));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Я прочитал множество решений, например использование шаблона проектирования команд, но не могу понять, как лучше всего решить эту проблему.
Подробнее здесь:
https://stackoverflow.com/questions/791 ... ava-spring
1729945917
Anonymous
вот у меня есть обработчик WebSocket, он содержит огромный переключатель для обработки входящих запросов, как решить эту проблему [code]@RequiredArgsConstructor @Component public class EditorOperationsWebSocketHandler extends TextWebSocketHandler { private final MessageParser messageParser; private final ProjectService projectService; private final FolderService folderService; private final FileService fileService; private final CommentService commentService; private final DiscussionService discussionService; private final ConcurrentHashMap projectSessions = new ConcurrentHashMap(); private final ConcurrentHashMap discussionSessions = new ConcurrentHashMap(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { String username = (String) session.getAttributes().get("sub"); Integer projectId = (Integer) session.getAttributes().get("projectId"); if (username != null && projectId != null) { projectSessions.computeIfAbsent(projectId, k -> new ConcurrentLinkedQueue()).add(session); System.out.println("Session added for project ID: " + projectId + " with user: " + username); } else { session.close(CloseStatus.NOT_ACCEPTABLE); } } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) { String payload = message.getPayload(); System.out.println("Received message: " + payload); handleMessage(session, payload); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { //cleanup(session); } public void handleMessage(WebSocketSession session, String jsonMessage) { try { Message message = messageParser.parseMessage(jsonMessage); System.out.println(message.getData()); Integer projectId = (Integer) session.getAttributes().get("projectId"); Integer userId = (Integer) session.getAttributes().get("userId"); switch (message.getAction()) { case "create-file": Message createFileDTOMessage = messageParser.parseMessage(jsonMessage, CreateFileDTO.class); var file = fileService.createFileByUser(createFileDTOMessage.getData(), userId); broadcastMessageToProjectMembers(projectId, new Message("get-project-structure", projectService.getFolderTree(projectId))); break; case "delete-file": Message deleteFileDTOMessage = messageParser.parseMessage(jsonMessage, Integer.class); fileService.deleteFile(deleteFileDTOMessage.getData()); broadcastMessageToProjectMembers(projectId, new Message("get-project-structure", projectService.getFolderTree(projectId))); break; case "create-folder": Message createFolderDTOMessage = messageParser.parseMessage(jsonMessage, CreateFolderDTO.class); var folder = folderService.createFolder(createFolderDTOMessage.getData()); broadcastMessageToProjectMembers(projectId, new Message("get-project-structure", projectService.getFolderTree(projectId))); break; case "create-primary-folder": Message createPrimaryFolderDTOMessage = messageParser.parseMessage(jsonMessage, CreatePrimaryFolderDTO.class); var primaryFolder = folderService.createPrimaryFolder(createPrimaryFolderDTOMessage.getData()); broadcastMessageToProjectMembers(projectId, new Message("get-project-structure", projectService.getFolderTree(projectId))); break; case "delete-folder": Message deleteFolderDTO = messageParser.parseMessage(jsonMessage, Integer.class); folderService.delete(deleteFolderDTO.getData()); broadcastMessageToProjectMembers(projectId, new Message("get-project-structure", projectService.getFolderTree(projectId))); break; case "edit-file": Message updateFileDTO = messageParser.parseMessage(jsonMessage, UpdateFileDTO.class); fileService.editFileByUser(updateFileDTO.getData(), userId); var readFileDTO = new ReadFileDTO(fileService.getFileById(updateFileDTO.getData().fileId()), updateFileDTO.getData().fileId()); broadcastMessageToProjectMembersExceptSender(session, projectId, new Message("get-file-content", readFileDTO)); break; case "create-comment": Message createCommentDTOMessage = messageParser.parseMessage(jsonMessage, CreateCommentDTO.class); var savedComment= commentService.createComment(createCommentDTOMessage.getData()); broadcastMessageToDiscussionMembers(createCommentDTOMessage.getData().discussionId(), new Message("get-comment", savedComment)); break; case "create-discussion": Message createDiscussionDTOMessage = messageParser.parseMessage(jsonMessage, CreateDiscussionDTO.class); var savedDiscussion=discussionService.createDiscussion(createDiscussionDTOMessage.getData()); broadcastMessageToProjectMembers(projectId,new Message("get-discussion", savedDiscussion)); break; case "join-discussion": Message joinDiscussionDTOMessage = messageParser.parseMessage(jsonMessage, JoinDiscussionDTO.class); discussionSessions.computeIfAbsent(joinDiscussionDTOMessage.getData().discussionId(), k -> new ConcurrentLinkedQueue()).add(session); sendMessage(session, new Message("join-discussion-done","join discussion done")); break; case "exit-discussion": Message exitDiscussionDTOMessage = messageParser.parseMessage(jsonMessage, JoinDiscussionDTO.class); discussionSessions.get(exitDiscussionDTOMessage.getData().discussionId()).remove(session); sendMessage(session, new Message("exit-discussion-done","exit discussion done")); break; case "project-structure": sendMessage(session, new Message("get-project-structure", projectService.getFolderTree(projectId))); break; default: //System.out.println("Unknown action: " + executionMessage.getAction()); break; } } catch (IOException e) { e.printStackTrace(); } } private void broadcastMessageToProjectMembers(Integer projectId, Message messageContent) { ConcurrentLinkedQueue sessions = projectSessions.get(projectId); broadcastMessageToMembers(sessions, messageContent); } private void broadcastMessageToDiscussionMembers(Integer discussionId, Message messageContent) { ConcurrentLinkedQueue sessions = discussionSessions.get(discussionId); broadcastMessageToMembers(sessions, messageContent); } private void broadcastMessageToMembers(ConcurrentLinkedQueue sessions, Message messageContent) { if (sessions != null) { try { TextMessage message = new TextMessage(messageParser.parseMessage(messageContent)); for (WebSocketSession session : sessions) { if (session.isOpen()) { session.sendMessage(message); } } } catch (IOException e) { e.printStackTrace(); } } } private void broadcastMessageExceptSender(ConcurrentLinkedQueue sessions, WebSocketSession senderSession, Message messageContent) { if (sessions != null) { try { String jsonMessage = messageParser.parseMessage(messageContent); TextMessage message = new TextMessage(jsonMessage); for (WebSocketSession session : sessions) { if (session.isOpen() && !session.getId().equals(senderSession.getId())) { session.sendMessage(message); } } } catch (IOException e) { e.printStackTrace(); } } } private void broadcastMessageToDiscussionMembersExceptSender(WebSocketSession senderSession, Integer discussionId, Message messageContent) { ConcurrentLinkedQueue sessions = discussionSessions.get(discussionId); broadcastMessageExceptSender(sessions, senderSession, messageContent); } private void broadcastMessageToProjectMembersExceptSender(WebSocketSession senderSession, Integer projectId, Message messageContent) { ConcurrentLinkedQueue sessions = projectSessions.get(projectId); broadcastMessageExceptSender(sessions, senderSession, messageContent); } private void sendMessage(WebSocketSession session, Message message) { if (session.isOpen()) { try { String jsonMessage = messageParser.parseMessage(message); session.sendMessage(new TextMessage(jsonMessage)); } catch (IOException e) { e.printStackTrace(); } } } } [/code] Я прочитал множество решений, например использование шаблона проектирования команд, но не могу понять, как лучше всего решить эту проблему. Подробнее здесь: [url]https://stackoverflow.com/questions/79128534/how-to-solve-big-switch-in-websocket-handler-in-java-spring[/url]