<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nouha50215</title>
    <description>The latest articles on DEV Community by Nouha50215 (@nouha50215).</description>
    <link>https://dev.to/nouha50215</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4201173%2F78535713-3372-439b-91cb-050ddbf4bee9.png</url>
      <title>DEV Community: Nouha50215</title>
      <link>https://dev.to/nouha50215</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nouha50215"/>
    <language>en</language>
    <item>
      <title>Building a Multi-Client Chat App with Java Sockets, Virtual Threads and JavaFX</title>
      <dc:creator>Nouha50215</dc:creator>
      <pubDate>Thu, 22 Oct 2026 20:05:00 +0000</pubDate>
      <link>https://dev.to/nouha50215/building-a-multi-client-chat-app-with-java-sockets-virtual-threads-and-javafx-53nk</link>
      <guid>https://dev.to/nouha50215/building-a-multi-client-chat-app-with-java-sockets-virtual-threads-and-javafx-53nk</guid>
      <description>&lt;h1&gt;
  
  
  Building a Multi-Client Chat App with Java Sockets, Virtual Threads and JavaFX
&lt;/h1&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TCPServer&lt;/strong&gt;: accepts many clients at the same time, adds the sender's name and time to every message (&lt;code&gt;[alice 14:05] hello&lt;/code&gt;) and sends it to everyone. Its window shows an activity log and a live list of connected users, each with a random colour.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TCPClient&lt;/strong&gt;: asks for a username, then opens the chat. Users send with a SEND button or Enter, type &lt;code&gt;allUsers&lt;/code&gt; to see who is online, and leave with &lt;code&gt;bye&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt; or a LEAVE button. An "Online" label with a green circle shows the connection status. Joining without a username gives &lt;strong&gt;read-only mode&lt;/strong&gt;: you can read but not send.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Development process
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Planning from the requirements.&lt;/strong&gt; I turned the requirements document into a checklist and a short plan, then chose the architecture before writing code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Architecture.&lt;/strong&gt; Both programs have the same layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model&lt;/strong&gt; (business logic): sockets, threads and the message protocol, with &lt;strong&gt;no JavaFX imports&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;View&lt;/strong&gt;: the JavaFX windows (GridPane + CSS).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Config&lt;/strong&gt;: reads the server address and port from &lt;code&gt;config.properties&lt;/code&gt; at runtime, so nothing needs recompiling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model reports events through small listener interfaces (&lt;code&gt;ServerListener&lt;/code&gt;, &lt;code&gt;MessageListener&lt;/code&gt;) that the view implements. This is the Observer pattern, and it keeps the logic independent of the UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Threading.&lt;/strong&gt; The server uses &lt;strong&gt;one virtual thread per client&lt;/strong&gt; (Java 21). Each client's thread spends most of its time waiting in &lt;code&gt;readLine()&lt;/code&gt;, and virtual threads make that waiting almost free: the JVM parks them and frees the underlying OS thread. Shared data uses &lt;code&gt;ConcurrentHashMap&lt;/code&gt;, and writes to each client are &lt;code&gt;synchronized&lt;/code&gt; so lines never get mixed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Tools.&lt;/strong&gt; 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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical challenges
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Running the JARs from the command line.&lt;/strong&gt; The app worked in IntelliJ but not from cmd at first. I learned to build with Maven &lt;code&gt;clean&lt;/code&gt; + &lt;code&gt;package&lt;/code&gt;, use the right JAR (not &lt;code&gt;original-…jar&lt;/code&gt;), and run with a Java 21+ JDK. IntelliJ's terminal made this easy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understanding virtual threads.&lt;/strong&gt; 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.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread safety.&lt;/strong&gt; Several threads broadcast at once, so I had to understand why a plain &lt;code&gt;HashMap&lt;/code&gt; isn't safe and why each client's writer needs a lock.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exporting UML diagrams.&lt;/strong&gt; PlantUML's online editor wouldn't save a PNG directly, so I used a screenshot or the IntelliJ PlantUML plugin.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;README images not showing on GitHub.&lt;/strong&gt; My screenshot file names had spaces, which break Markdown image links. Renaming the files fixed it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final implementation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Multi-client server with virtual threads&lt;/li&gt;
&lt;li&gt;Broadcast messages with username + time&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allUsers&lt;/code&gt; command (reply only to the requester)&lt;/li&gt;
&lt;li&gt;Read-only mode&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bye&lt;/code&gt; / &lt;code&gt;end&lt;/code&gt; / LEAVE with notifications to the others&lt;/li&gt;
&lt;li&gt;Online status indicator, coloured user list, server activity log&lt;/li&gt;
&lt;li&gt;Host and port loaded from &lt;code&gt;config.properties&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Model fully independent of the JavaFX view&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Source code:&lt;/strong&gt; [&lt;a href="https://github.com/Nouha50215/Multi-Client-Chat" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;]&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learned
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

</description>
      <category>java</category>
      <category>networking</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
