[Client] (add) UI thread, Login panel

This commit is contained in:
lethanhdat committed 2024-12-27 00:40:27 -06:00
1 parent 9233ee3059
commit 645c6ed70f
6 files changed
+131 -62

No files matched your search

+56 -36
View File
@@ -1,6 +1,7 @@
package BsK.client;
import BsK.client.network.handler.ClientHandler;
import BsK.client.ui.handler.UIHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
@@ -15,45 +16,64 @@ import io.netty.handler.codec.http.websocketx.WebSocketClientProtocolHandler;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import io.netty.handler.timeout.IdleStateHandler;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class Client {
public static void main(String[] args) throws Exception {
var serverAddress = "localhost";
var port = 1999;
URI uri = new URI("ws://" + serverAddress + ":" + port + "/");
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap =
new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(
new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline()
.addLast(new IdleStateHandler(60 * 30, 0, 0, TimeUnit.SECONDS))
.addLast(new HttpClientCodec())
.addLast(new HttpObjectAggregator(8192))
.addLast(
new WebSocketClientProtocolHandler(
uri,
WebSocketVersion.V13,
null,
true,
new DefaultHttpHeaders(),
100000))
.addLast("ws", new ClientHandler());
}
});
log.info("Connecting to {}:{}", serverAddress, port);
Channel channel = bootstrap.connect(serverAddress, port).sync().channel();
channel.closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
public static void main(String[] args) throws Exception {
var thread = new Thread(() -> {
var serverAddress = "localhost";
var port = 1999;
URI uri = null;
try {
uri = new URI("ws://" + serverAddress + ":" + port + "/");
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
EventLoopGroup group = new NioEventLoopGroup();
try {
URI finalUri = uri;
Bootstrap bootstrap =
new Bootstrap()
.group(group)
.channel(NioSocketChannel.class)
.handler(
new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline()
.addLast(new IdleStateHandler(60 * 30,
0, 0, TimeUnit.SECONDS))
.addLast(new HttpClientCodec())
.addLast(new HttpObjectAggregator(8192))
.addLast(
new WebSocketClientProtocolHandler(
finalUri,
WebSocketVersion.V13,
null,
true,
new DefaultHttpHeaders(),
100000))
.addLast("ws", ClientHandler.INSTANCE);
}
});
log.info("Connecting to {}:{}", serverAddress, port);
Channel channel = bootstrap.connect(serverAddress, port).sync().channel();
channel.closeFuture().sync();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
try {
group.shutdownGracefully().sync();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
thread.start();
UIHandler.INSTANCE.showUI();
}
}
}
}
@@ -1,11 +1,10 @@
package BsK.client.network.handler;
import BsK.client.ui.handler.UIHandler;
import BsK.common.packet.Packet;
import BsK.common.packet.PacketSerializer;
import BsK.common.packet.req.GetPatientInfoReq;
import BsK.common.packet.req.LoginRequest;
import BsK.common.packet.res.ErrorResponse;
import BsK.common.packet.res.GetPatientInfoRes;
import BsK.common.packet.res.HandshakeCompleteResponse;
import BsK.common.packet.res.LoginSuccessResponse;
import BsK.common.util.network.NetworkUtil;
@@ -19,7 +18,8 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
public class ClientHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
public static ChannelHandlerContext ctx;
public static final ClientHandler INSTANCE = new ClientHandler();
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) {
log.debug("Received message: {}", frame.text());
@@ -27,8 +27,9 @@ public class ClientHandler extends SimpleChannelInboundHandler<TextWebSocketFram
switch (packet) {
case HandshakeCompleteResponse handshakeCompleteResponse -> {
log.info("Handshake complete");
var login = new LoginRequest("user", "user");
NetworkUtil.sendPacket(ctx.channel(), login);
this.ctx = ctx;
// var login = new LoginRequest("user", "user");
// NetworkUtil.sendPacket(ctx.channel(), login);
}
case ErrorResponse response -> {
log.error("Received error response: {}", response.getError());
@@ -37,16 +38,7 @@ public class ClientHandler extends SimpleChannelInboundHandler<TextWebSocketFram
default -> log.error("Received error response: {}", response.getError());
}
}
case LoginSuccessResponse loginSuccessResponse -> {
log.info("Received login success response, id {}, rold {}", loginSuccessResponse.getId(), loginSuccessResponse.getRole());
// Chỉ để demo, chỉ nên request khi mà user click lấy list user hay gì đó
var getPatientInfoReq = new GetPatientInfoReq("");
NetworkUtil.sendPacket(ctx.channel(), getPatientInfoReq);
}
case GetPatientInfoRes getPatientInfoRes -> {
log.info("Received get patient info {}", PacketSerializer.GSON.toJson(getPatientInfoRes));
}
case LoginSuccessResponse loginSuccessResponse -> log.info("Received login success response");
case null, default -> log.warn("Unknown message: {}", frame.text());
}
}
@@ -0,0 +1,65 @@
package BsK.client.ui.handler;
import BsK.client.network.handler.ClientHandler;
import BsK.common.packet.Packet;
import BsK.common.packet.req.LoginRequest;
import BsK.common.packet.res.HandshakeCompleteResponse;
import BsK.common.packet.res.LoginSuccessResponse;
import BsK.common.util.network.NetworkUtil;
import lombok.extern.slf4j.Slf4j;
import javax.swing.*;
@Slf4j
public class UIHandler {
public static final UIHandler INSTANCE = new UIHandler();
boolean isLoggedIn = false;
int id = -1;
boolean readyToLogin = false;
public void onPacket(Packet packet) {
switch (packet) {
case HandshakeCompleteResponse response:
System.out.println("Received handshake complete response");
readyToLogin = true;
break;
case LoginSuccessResponse response:
log.info("Received login success response: " + response.getUserId() + " " + response.getRole());
break;
default:
return;
}
}
public void showUI() {
JTextField usernameField = new JTextField();
JPasswordField passwordField = new JPasswordField();
Object[] message = {
"Username:", usernameField,
"Password:", passwordField
};
int option = JOptionPane.showConfirmDialog(null, message, "Login", JOptionPane.OK_CANCEL_OPTION);
if (option == JOptionPane.OK_OPTION) {
String username = usernameField.getText();
String password = new String(passwordField.getPassword());
System.out.println("Username: " + username);
System.out.println("Password: " + password);
var login = new LoginRequest(username, password);
NetworkUtil.sendPacket(ClientHandler.ctx.channel(), login);
} else {
System.out.println("Login canceled");
}
}
// public void onClickButtonLogin() {
// if (!readyToLogin) {
// // TODO: hiển thị lỗi "Chưa kết nối tới server"
// return;
// }
// var username = "username"; // Đọc từ đâu đó
// var password = "password"; // Đọc từ đâu đó
//
// NetworkUtil.sendPacket(ctx.channel(), login);
// NetworkUtil.sendPacket(loginRequest);
// }
}
@@ -9,14 +9,6 @@ import java.time.LocalDateTime;
@AllArgsConstructor
@Data
public class LoginRequest implements Packet {
String username;
String password;
LocalDateTime timestamp;
public LoginRequest(String username, String password) {
this.username = username;
this.password = password;
this.timestamp = LocalDateTime.now(); // Automatically sets the current time
}
}
@@ -1,13 +1,13 @@
package BsK.common.packet.res;
import BsK.common.packet.Packet;
import BsK.server.network.entity.Role;
import BsK.common.packet.Packet;
import lombok.AllArgsConstructor;
import lombok.Data;
@AllArgsConstructor
@Data
public class LoginSuccessResponse implements Packet {
int id;
Role role;
int userId;
Role role;
}
Binary file not shown.