[update] Implement connection error handling in Client class with user-friendly dialog messages. Enhance server startup process with dashboard updates for better visibility of server status. Refactor user session management in ServerHandler to ensure accurate role updates and connection tracking.

This commit is contained in:
Lê Thành Đạt committed 2025-06-09 15:54:22 +07:00
1 parent 46182568a5
commit bc78cdf1f4
7 files changed
+201 -100

No files matched your search

+55 -17
View File
@@ -24,12 +24,54 @@ import java.util.Properties;
import java.io.IOException;
import java.io.File;
import java.nio.file.Files;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
@Slf4j
public class Client {
private static void showConnectionErrorDialog(String serverAddress, int port, Exception error) {
SwingUtilities.invokeLater(() -> {
String message = String.format(
"""
Không thể kết nối đến máy chủ!
Địa chỉ máy chủ: %s
Cổng: %d
Nguyên nhân có thể:
1. Máy chủ chưa được khởi động
2. Địa chỉ hoặc cổng không chính xác
3. Tường lửa đang chặn kết nối
Giải pháp:
1. Kiểm tra xem máy chủ đã được khởi động chưa
2. Kiểm tra lại cấu hình trong file config.properties
3. Tắt ứng dụng và khởi động lại
Chi tiết lỗi: %s
""",
serverAddress,
port,
error.getMessage()
);
JOptionPane.showMessageDialog(
null,
message,
"Lỗi Kết Nối",
JOptionPane.ERROR_MESSAGE
);
// Exit the application after showing the error
System.exit(1);
});
}
public static void main(String[] args) throws Exception {
var thread = new Thread(() -> {
Properties props = new Properties();
String serverAddress = "localhost";
int port = 1999;
// First try to load from external config file
File externalConfig = new File("config/config.properties");
@@ -47,37 +89,32 @@ public class Client {
try (InputStream input = Client.class.getClassLoader().getResourceAsStream("config.properties")) {
if (input == null) {
log.error("Unable to find config.properties");
showConnectionErrorDialog(serverAddress, port,
new Exception("Không tìm thấy file cấu hình config.properties"));
return;
}
props.load(input);
log.info("Loaded configuration from internal resources");
} catch (IOException e) {
log.error("Error loading internal config file", e);
showConnectionErrorDialog(serverAddress, port, e);
return;
}
}
// Get server configuration
var serverAddress = props.getProperty("server.address");
var portStr = props.getProperty("server.port");
serverAddress = props.getProperty("server.address", "localhost");
String portStr = props.getProperty("server.port");
// Use defaults if not configured
if (serverAddress == null) {
serverAddress = "localhost";
log.info("Using default server address: {}", serverAddress);
} else {
log.info("Using configured server address: {}", serverAddress);
}
int port;
if (portStr != null) {
port = Integer.parseInt(portStr);
log.info("Using configured port: {}", port);
} else {
port = 1999;
log.info("Using default port: {}", port);
}
log.info("Using server address: {}", serverAddress);
if ("127.0.0.1".equals(serverAddress)) {
log.info("Connecting to localhost");
}
@@ -86,8 +123,10 @@ public class Client {
try {
uri = new URI("ws://" + serverAddress + ":" + port + "/");
} catch (URISyntaxException e) {
throw new RuntimeException(e);
showConnectionErrorDialog(serverAddress, port, e);
return;
}
EventLoopGroup group = new NioEventLoopGroup();
try {
URI finalUri = uri;
@@ -120,18 +159,17 @@ public class Client {
channel.closeFuture().sync();
} catch (Exception e) {
throw new RuntimeException(e);
log.error("Connection error", e);
showConnectionErrorDialog(serverAddress, port, e);
return;
} finally {
try {
group.shutdownGracefully().sync();
} catch (InterruptedException e) {
throw new RuntimeException(e);
log.error("Error shutting down", e);
}
}
});
thread.start();
}
}
@@ -398,7 +398,7 @@ public class CheckUpPage extends JPanel {
// Configure the Details/Actions Panel (rightBottomPanel)
rightBottomPanel.setLayout(new BorderLayout());
rightBottomPanel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5),
BorderFactory.createEmptyBorder(5, 5, 5, 5),
BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(new Color(63, 81, 181), 1, true),
"Chi tiết và Thao tác",
@@ -974,7 +974,7 @@ public class CheckUpPage extends JPanel {
// Create a more modern action panel
JPanel iconPanel = new JPanel(new GridLayout(1, 5, 10, 0)); // 5 buttons, 10px horizontal gap
iconPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
iconPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
iconPanel.setBackground(Color.WHITE);
// Define button properties
@@ -994,9 +994,9 @@ public class CheckUpPage extends JPanel {
JButton button = createActionButton(name, text, color);
button.addActionListener(e -> {
if (checkupIdField == null || checkupIdField.getText().isEmpty()) {
JOptionPane.showMessageDialog(null, "Vui lòng chọn một bệnh nhân từ hàng đợi", "Chưa chọn bệnh nhân", JOptionPane.WARNING_MESSAGE);
return;
}
JOptionPane.showMessageDialog(null, "Vui lòng chọn một bệnh nhân từ hàng đợi", "Chưa chọn bệnh nhân", JOptionPane.WARNING_MESSAGE);
return;
}
handleActionPanelClick(name);
});
iconPanel.add(button);
@@ -1101,53 +1101,53 @@ public class CheckUpPage extends JPanel {
private void handleActionPanelClick(String name) {
switch (name) {
case "service":
if(serDialog == null) {
serDialog = new ServiceDialog(mainFrame);
}
serDialog.setVisible(true);
saved = false;
servicePrescription = serDialog.getServicePrescription();
updatePrescriptionTree();
log.info("Service prescription: {}", (Object) servicePrescription);
break;
case "save": {
int option = JOptionPane.showOptionDialog(null, "Bạn có muốn lưu các thay đổi?",
"Lưu thay đổi", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
null, null, null);
if (option == JOptionPane.NO_OPTION) {
return;
}
saved = true;
callingStatusLabel.setBackground(new Color(230, 255, 230));
callingStatusLabel.setForeground(new Color(0, 100, 0));
// TODO: Add logic to actually save medicinePrescription and servicePrescription with other checkup data
break;
}
case "medicine":
if(medDialog == null) {
medDialog = new MedicineDialog(mainFrame);
}
medDialog.setVisible(true);
saved = false;
medicinePrescription = medDialog.getMedicinePrescription();
updatePrescriptionTree();
log.info("Medicine prescription: {}", (Object) medicinePrescription);
break;
case "printer":
if ((medicinePrescription == null || medicinePrescription.length == 0) &&
(servicePrescription == null || servicePrescription.length == 0)) {
if(serDialog == null) {
serDialog = new ServiceDialog(mainFrame);
}
serDialog.setVisible(true);
saved = false;
servicePrescription = serDialog.getServicePrescription();
updatePrescriptionTree();
log.info("Service prescription: {}", (Object) servicePrescription);
break;
case "save": {
int option = JOptionPane.showOptionDialog(null, "Bạn có muốn lưu các thay đổi?",
"Lưu thay đổi", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
null, null, null);
if (option == JOptionPane.NO_OPTION) {
return;
}
saved = true;
callingStatusLabel.setBackground(new Color(230, 255, 230));
callingStatusLabel.setForeground(new Color(0, 100, 0));
// TODO: Add logic to actually save medicinePrescription and servicePrescription with other checkup data
break;
}
case "medicine":
if(medDialog == null) {
medDialog = new MedicineDialog(mainFrame);
}
medDialog.setVisible(true);
saved = false;
medicinePrescription = medDialog.getMedicinePrescription();
updatePrescriptionTree();
log.info("Medicine prescription: {}", (Object) medicinePrescription);
break;
case "printer":
if ((medicinePrescription == null || medicinePrescription.length == 0) &&
(servicePrescription == null || servicePrescription.length == 0)) {
JOptionPane.showMessageDialog(null, "Không có thuốc hoặc dịch vụ để in.", "Không có dữ liệu", JOptionPane.INFORMATION_MESSAGE);
return;
}
MedicineInvoice medicineInvoice = new MedicineInvoice(checkupIdField.getText(),
customerLastNameField.getText() + " " + customerFirstNameField.getText(),
dobPicker.getJFormattedTextField().getText(), customerPhoneField.getText(),
genderComboBox.getSelectedItem().toString(),
customerAddressField.getText() + ", " + (wardComboBox.getSelectedItem() != null ? wardComboBox.getSelectedItem().toString() : "") + ", " + (districtComboBox.getSelectedItem() != null ? districtComboBox.getSelectedItem().toString() : "") + ", " + (provinceComboBox.getSelectedItem() != null ? provinceComboBox.getSelectedItem().toString() : ""),
doctorComboBox.getSelectedItem().toString(), diagnosisField.getText(),
notesField.getText(), medicinePrescription, servicePrescription);
medicineInvoice.createDialog(mainFrame);
break;
}
MedicineInvoice medicineInvoice = new MedicineInvoice(checkupIdField.getText(),
customerLastNameField.getText() + " " + customerFirstNameField.getText(),
dobPicker.getJFormattedTextField().getText(), customerPhoneField.getText(),
genderComboBox.getSelectedItem().toString(),
customerAddressField.getText() + ", " + (wardComboBox.getSelectedItem() != null ? wardComboBox.getSelectedItem().toString() : "") + ", " + (districtComboBox.getSelectedItem() != null ? districtComboBox.getSelectedItem().toString() : "") + ", " + (provinceComboBox.getSelectedItem() != null ? provinceComboBox.getSelectedItem().toString() : ""),
doctorComboBox.getSelectedItem().toString(), diagnosisField.getText(),
notesField.getText(), medicinePrescription, servicePrescription);
medicineInvoice.createDialog(mainFrame);
break;
case "ultrasound":
JOptionPane.showMessageDialog(null, "Tính năng in kết quả siêu âm sẽ được triển khai.", "TODO", JOptionPane.INFORMATION_MESSAGE);
break;
+18
View File
@@ -16,6 +16,7 @@ import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -119,6 +120,12 @@ public class Server {
}
public static void main(String[] args) throws InterruptedException, SQLException {
// Initialize and show server dashboard
ServerDashboard dashboard = ServerDashboard.getInstance();
dashboard.setVisible(true);
dashboard.updateStatus("Starting...", Color.ORANGE);
dashboard.updatePort(PORT);
EventLoopGroup parentGroup =
Epoll.isAvailable() ? new EpollEventLoopGroup() : new NioEventLoopGroup();
EventLoopGroup childGroup =
@@ -152,8 +159,19 @@ public class Server {
log.info("To connect, clients should use:");
log.info(" - If on same machine: ws://localhost:{} or ws://127.0.0.1:{}", PORT, PORT);
log.info(" - If on network: ws://<this-computer's-ip>:{}", PORT);
// Update dashboard status to running
dashboard.updateStatus("Running", Color.GREEN);
dashboard.addLog("Server started successfully on port " + PORT);
f.channel().closeFuture().sync();
} catch (Exception e) {
dashboard.updateStatus("Error", Color.RED);
dashboard.addLog("Server error: " + e.getMessage());
throw e;
} finally {
dashboard.updateStatus("Shutting down", Color.ORANGE);
dashboard.addLog("Server shutting down...");
parentGroup.shutdownGracefully();
childGroup.shutdownGracefully();
}
@@ -265,15 +265,17 @@ public class ServerDashboard extends JFrame {
}
public static void decrementClients() {
connectedClients--;
connectedClients = Math.max(0, connectedClients - 1); // Ensure we don't go below 0
updateClientCount();
}
private static void updateClientCount() {
if (instance != null) {
SwingUtilities.invokeLater(() ->
instance.clientsLabel.setText("Connected Clients: " + connectedClients)
);
SwingUtilities.invokeLater(() -> {
instance.clientsLabel.setText("Connected Clients: " + connectedClients);
// Also update the network table since client count changed
instance.refreshNetworkTable();
});
}
}
@@ -22,7 +22,6 @@ public class User {
public User(Channel channel, int sessionId) {
this.channel = channel;
this.sessionId = sessionId;
}
public void authenticate(String username, String password) {
@@ -36,14 +35,13 @@ public class User {
log.info(rs.getString("user_name") + " logged in");
role = Role.valueOf(rs.getString("role_name"));
userId = rs.getInt("user_id");
// Update the client connection with the new role
SessionManager.updateUserRole(channel.id().asLongText(), role.toString(), userId);
}
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public boolean isAuthenticated() {
@@ -8,6 +8,7 @@ import BsK.common.packet.res.ErrorResponse.Error;
import BsK.common.entity.Status;
import BsK.common.util.date.DateUtils;
import BsK.server.Server;
import BsK.server.ServerDashboard;
import BsK.server.network.manager.SessionManager;
import BsK.server.network.util.UserUtil;
import io.netty.channel.ChannelHandlerContext;
@@ -39,6 +40,12 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) {
log.debug("Received message: {}", frame.text());
// Update last activity time for the client
var connectedUser = SessionManager.getUserByChannel(ctx.channel().id().asLongText());
if (connectedUser != null) {
ServerDashboard.getInstance().refreshNetworkTable();
}
Packet packet = PacketSerializer.GSON.fromJson(frame.text(), Packet.class);
@@ -51,6 +58,8 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
if (user.isAuthenticated()) {
UserUtil.sendPacket(user.getSessionId(), new LoginSuccessResponse(user.getUserId(), user.getRole()));
log.info("Send response to client User {} authenticated, role {}, session {}", user.getUserId(), user.getRole(), user.getSessionId());
// Update client connection info
SessionManager.updateUserRole(ctx.channel().id().asLongText(), user.getRole().toString(), user.getUserId());
} else {
log.info("User {} failed to authenticate", user.getUserId());
UserUtil.sendPacket(user.getSessionId(), new ErrorResponse(Error.INVALID_CREDENTIALS));
@@ -63,9 +72,9 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
// Tạo user trong database hoặc check exist
boolean isUserExist = false;
} else if (packet instanceof LogoutRequest) {
var user = SessionManager.getUserByChannel(ctx.channel().id().asLongText());
if (user != null) {
log.info("User {} (Session {}) requested logout.", user.getUserId(), user.getSessionId());
var logoutUser = SessionManager.getUserByChannel(ctx.channel().id().asLongText());
if (logoutUser != null) {
log.info("User {} (Session {}) requested logout.", logoutUser.getUserId(), logoutUser.getSessionId());
SessionManager.onUserDisconnect(ctx.channel());
// Optionally, you could send a LogoutResponse back to the client if needed,
// but since the client navigates away, it might not be processed.
@@ -74,8 +83,8 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
}
} else {
// Check if user is authenticated
var user = SessionManager.getUserByChannel(ctx.channel().id().asLongText());
if (!user.isAuthenticated()) {
var currentUser = SessionManager.getUserByChannel(ctx.channel().id().asLongText());
if (!currentUser.isAuthenticated()) {
log.warn("Received packet from unauthenticated user: {}", packet);
return;
}
@@ -140,7 +149,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
for (int i = 0; i < resultString.length; i++) {
resultArray[i] = resultString[i].split("\\|");
}
UserUtil.sendPacket(user.getSessionId(), new GetCheckUpQueueResponse(resultArray));
UserUtil.sendPacket(currentUser.getSessionId(), new GetCheckUpQueueResponse(resultArray));
}
} catch (SQLException e) {
throw new RuntimeException(e);
@@ -237,7 +246,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
resultList.add(doctorName);
}
String[] resultString = resultList.toArray(new String[0]);
UserUtil.sendPacket(user.getSessionId(), new GetDoctorGeneralInfoResponse(resultString));
UserUtil.sendPacket(currentUser.getSessionId(), new GetDoctorGeneralInfoResponse(resultString));
log.info("Send response to client GetDoctorGeneralInfo");
}
}
@@ -260,7 +269,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
if (!rs.isBeforeFirst()) {
System.out.println("No history data found in the checkup table.");
UserUtil.sendPacket(user.getSessionId(), new GetCustomerHistoryResponse(new String[0][7]));
UserUtil.sendPacket(currentUser.getSessionId(), new GetCustomerHistoryResponse(new String[0][7]));
} else {
ArrayList<String> resultList = new ArrayList<>();
while (rs.next()) {
@@ -286,7 +295,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
resultArray[i] = resultString[i].split("\\|");
}
UserUtil.sendPacket(user.getSessionId(), new GetCustomerHistoryResponse(resultArray));
UserUtil.sendPacket(currentUser.getSessionId(), new GetCustomerHistoryResponse(resultArray));
}
} catch (SQLException e) {
@@ -327,7 +336,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
resultArray[i] = resultString[i].split("\\|");
}
UserUtil.sendPacket(user.getSessionId(), new GetMedInfoResponse(resultArray));
UserUtil.sendPacket(currentUser.getSessionId(), new GetMedInfoResponse(resultArray));
}
} catch (SQLException e) {
throw new RuntimeException(e);
@@ -361,7 +370,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
resultArray[i] = resultString[i].split("\\|");
}
UserUtil.sendPacket(user.getSessionId(), new GetSerInfoResponse(resultArray));
UserUtil.sendPacket(currentUser.getSessionId(), new GetSerInfoResponse(resultArray));
}
} catch (SQLException e) {
throw new RuntimeException(e);
@@ -383,7 +392,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
String clinicAddress = rs.getString("address");
String clinicPhone = rs.getString("phone");
UserUtil.sendPacket(user.getSessionId(), new ClinicInfoResponse(clinicName, clinicAddress, clinicPhone));
UserUtil.sendPacket(currentUser.getSessionId(), new ClinicInfoResponse(clinicName, clinicAddress, clinicPhone));
}
}
catch (SQLException e) {
@@ -426,7 +435,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
resultArray[i] = resultString[i].split("\\|");
}
UserUtil.sendPacket(user.getSessionId(), new GetRecentPatientResponse(resultArray));
UserUtil.sendPacket(currentUser.getSessionId(), new GetRecentPatientResponse(resultArray));
}
} catch (SQLException e) {
throw new RuntimeException(e);
@@ -456,7 +465,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
}
String[] resultString = resultList.toArray(new String[0]);
UserUtil.sendPacket(user.getSessionId(), new GetProvinceResponse(resultString, provinceIdMap));
UserUtil.sendPacket(currentUser.getSessionId(), new GetProvinceResponse(resultString, provinceIdMap));
}
} catch (SQLException e) {
throw new RuntimeException(e);
@@ -493,7 +502,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
String[] resultString = resultList.toArray(new String[0]);
UserUtil.sendPacket(user.getSessionId(), new GetDistrictResponse(resultString, districtIdMap));
UserUtil.sendPacket(currentUser.getSessionId(), new GetDistrictResponse(resultString, districtIdMap));
}
} catch (SQLException e) {
throw new RuntimeException(e);
@@ -529,10 +538,10 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
}
String[] resultString = resultList.toArray(new String[0]);
UserUtil.sendPacket(user.getSessionId(), new GetWardResponse(resultString));
UserUtil.sendPacket(currentUser.getSessionId(), new GetWardResponse(resultString));
}
} catch (SQLException e) {
UserUtil.sendPacket(user.getSessionId(), new ErrorResponse(Error.SQL_EXCEPTION));
UserUtil.sendPacket(currentUser.getSessionId(), new ErrorResponse(Error.SQL_EXCEPTION));
throw new RuntimeException(e);
}
}
@@ -559,10 +568,10 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
customerId = rs.getInt(1);
}
UserUtil.sendPacket(user.getSessionId(), new AddPatientResponse(true, customerId, "Thêm bệnh nhân thành công"));
UserUtil.sendPacket(currentUser.getSessionId(), new AddPatientResponse(true, customerId, "Thêm bệnh nhân thành công"));
} catch (SQLException e) {
String errorMessage = e.getMessage();
UserUtil.sendPacket(user.getSessionId(), new AddPatientResponse(false,-1, "Lỗi: " + errorMessage));
UserUtil.sendPacket(currentUser.getSessionId(), new AddPatientResponse(false,-1, "Lỗi: " + errorMessage));
throw new RuntimeException(e);
}
}
@@ -598,7 +607,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
// Commit the transaction
Server.connection.commit();
UserUtil.sendPacket(user.getSessionId(), new AddCheckupResponse(true, "Thêm bệnh nhân thành công"));
UserUtil.sendPacket(currentUser.getSessionId(), new AddCheckupResponse(true, "Thêm bệnh nhân thành công"));
}
catch (SQLException e) {
try {
@@ -608,7 +617,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
log.error("Error during rollback", rollbackEx);
}
String errorMessage = e.getMessage();
UserUtil.sendPacket(user.getSessionId(), new AddCheckupResponse(false, "Lỗi: " + errorMessage));
UserUtil.sendPacket(currentUser.getSessionId(), new AddCheckupResponse(false, "Lỗi: " + errorMessage));
throw new RuntimeException(e);
}
finally {
@@ -638,9 +647,14 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
if (cause instanceof IOException) {
var user = SessionManager.getUserByChannel(ctx.channel().id().asLongText());
if (user != null) {
ServerDashboard.getInstance().addLog("Client disconnected: Session " + user.getSessionId());
}
SessionManager.onUserDisconnect(ctx.channel());
} else {
log.error("ERROR: ", cause);
ServerDashboard.getInstance().addLog("Error: " + cause.getMessage());
}
}
@@ -649,14 +663,21 @@ public class ServerHandler extends SimpleChannelInboundHandler<TextWebSocketFram
if (evt instanceof IdleStateEvent event) {
if (event.state() == IdleState.READER_IDLE) {
try {
var user = SessionManager.getUserByChannel(ctx.channel().id().asLongText());
if (user != null) {
ServerDashboard.getInstance().addLog("Client timed out: Session " + user.getSessionId());
}
SessionManager.onUserDisconnect(ctx.channel());
ctx.channel().close();
} catch (Exception e) {
ServerDashboard.getInstance().addLog("Error during client timeout: " + e.getMessage());
}
}
} else if (evt instanceof HandshakeComplete) {
int SessionId = SessionManager.onUserLogin(ctx.channel());
log.info("Session {} logged in", SessionId);
ServerDashboard.getInstance().addLog("New client connected: Session " + SessionId);
ServerDashboard.incrementClients();
UserUtil.sendPacket(SessionId, new HandshakeCompleteResponse());
} else {
@@ -1,7 +1,9 @@
package BsK.server.network.manager;
import BsK.server.network.entity.User;
import BsK.server.network.entity.ClientConnection;
import io.netty.channel.Channel;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
@@ -17,6 +19,8 @@ public class SessionManager {
private static final Map<String, User> CHANNEL_TO_USER_MAP = new ConcurrentHashMap<>();
private static final Map<String, ClientConnection> CHANNEL_TO_CONNECTION_MAP = new ConcurrentHashMap<>();
private static final AtomicInteger SESSION_ID = new AtomicInteger(0);
@@ -36,17 +40,37 @@ public class SessionManager {
return SESSION_ID.get();
}
public static Collection<ClientConnection> getAllConnections() {
return CHANNEL_TO_CONNECTION_MAP.values();
}
public static int onUserLogin(Channel channel) {
int sessionId = SESSION_ID.incrementAndGet();
var user = new User(channel, sessionId);
SESSION_ID_MAP.put(sessionId, channel.id().asLongText());
CHANNEL_SESSION_ID_MAP.put(channel.id().asLongText(), sessionId);
CHANNEL_TO_USER_MAP.put(channel.id().asLongText(), user);
var connection = new ClientConnection(channel, sessionId);
String channelId = channel.id().asLongText();
SESSION_ID_MAP.put(sessionId, channelId);
CHANNEL_SESSION_ID_MAP.put(channelId, sessionId);
CHANNEL_TO_USER_MAP.put(channelId, user);
CHANNEL_TO_CONNECTION_MAP.put(channelId, connection);
return sessionId;
}
public static void onUserDisconnect(Channel channel) {
int sessionId = CHANNEL_SESSION_ID_MAP.remove(channel.id().asLongText());
String channelId = channel.id().asLongText();
int sessionId = CHANNEL_SESSION_ID_MAP.remove(channelId);
SESSION_ID_MAP.remove(sessionId);
CHANNEL_TO_USER_MAP.remove(channelId);
CHANNEL_TO_CONNECTION_MAP.remove(channelId);
}
public static void updateUserRole(String channelId, String role, int userId) {
ClientConnection conn = CHANNEL_TO_CONNECTION_MAP.get(channelId);
if (conn != null) {
conn.setUserRole(role);
conn.setUserId(userId);
}
}
}