使用 Java Sockets、虛擬執行緒和 JavaFX 建立多用戶聊天應用程式
Building a Multi-Client Chat App with Java Sockets, Virtual Threads and JavaFX
作者以 Java Sockets、虛擬執行緒和 JavaFX 建立多用戶即時聊天應用程式,透過 TCP 連接多個用戶,並以 JavaFX 提供伺服器和用戶端介面。伺服器為每個用戶端使用一條虛擬執行緒,支援廣播帶有用戶名稱和時間的訊息,以及查看在線用戶;用戶端亦支援唯讀模式和離開通知。
Building a Multi-Client Chat App with Java Sockets, Virtual Threads and JavaFX
For my Advanced Distributed Programming course, I built a group chat application: one server, many clients, real-time messages over TCP, and a JavaFX interface on both sides.
What I built
-
TCPServer: accepts many clients at the same time, adds the sender's name and time to every message (
[alice 14:05] hello) and sends it to everyone. Its window shows an activity log and a live list of connected users, each with a random colour. -
TCPClient: asks for a username, then opens the chat. Users send with a SEND button or Enter, type
allUsersto see who is online, and leave withbye,endor a LEAVE button. An "Online" label with a green circle shows the connection status. Joining without a username gives read-only mode: you can read but not send.
Development process
1. Planning from the requirements. I turned the requirements document into a checklist and a short plan, then chose the architecture before writing code.
2. Architecture. Both programs have the same layers:
- Model (business logic): sockets, threads and the message protocol, with no JavaFX imports.
- View: the JavaFX windows (GridPane + CSS).
-
Config: reads the server address and port from
config.propertiesat runtime, so nothing needs recompiling.
The model reports events through small listener interfaces (ServerListener, MessageListener) that the view implements. This is the Observer pattern, and it keeps the logic independent of the UI.
3. Threading. The server uses one virtual thread per client (Java 21). Each client's thread spends most of its time waiting in readLine(), and virtual threads make that waiting almost free: the JVM parks them and frees the underlying OS thread. Shared data uses ConcurrentHashMap, and writes to each client are synchronized so lines never get mixed.
4. Tools. Two Maven projects (built into executable "fat" JARs with the shade plugin), IntelliJ IDEA, Git/GitHub with small commits, and PlantUML for the UML diagrams.
I used an AI assistant (Claude) to help plan the project and generate a first version of the code. Then I ran and tested everything, built the JARs, and spent time understanding how each part works, especially the threading.
Technical challenges
-
Running the JARs from the command line. The app worked in IntelliJ but not from cmd at first. I learned to build with Maven
clean+package, use the right JAR (notoriginal-…jar), and run with a Java 21+ JDK. IntelliJ's terminal made this easy. - Understanding virtual threads. At first I thought each virtual thread was tied to one platform thread. Actually, many virtual threads share a few "carrier" threads and only hold one while they are running.
-
Thread safety. Several threads broadcast at once, so I had to understand why a plain
HashMapisn't safe and why each client's writer needs a lock. - Exporting UML diagrams. PlantUML's online editor wouldn't save a PNG directly, so I used a screenshot or the IntelliJ PlantUML plugin.
- README images not showing on GitHub. My screenshot file names had spaces, which break Markdown image links. Renaming the files fixed it.
Final implementation
- Multi-client server with virtual threads
- Broadcast messages with username + time
-
allUserscommand (reply only to the requester) - Read-only mode
-
bye/end/ LEAVE with notifications to the others - Online status indicator, coloured user list, server activity log
- Host and port loaded from
config.properties - Model fully independent of the JavaFX view
Source code: GitHub repo
Demo video: Watch the demo
What I learned
Java sockets and I/O streams, multithreading with virtual threads, thread-safe collections, client-server architecture, separating logic from UI, and building and packaging a Java app with Maven.
來源:DEV Community · dev.to