DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Jakarta WebSocket Essentials: A Guide to Full-Duplex Communication in Java
  • Full-Duplex Scalable Client-Server Communication with WebSockets and Spring Boot (Part I)
  • Beyond Linguistics: Real-Time Domain Event Mapping with WebSocket and Spring Boot
  • Recurrent Workflows With Cloud Native Dapr Jobs

Trending

  • Unlocking AI Coding Assistants Part 4: Generate Spring Boot Application
  • Understanding Java Signals
  • A Guide to Container Runtimes
  • Building Scalable and Resilient Data Pipelines With Apache Airflow
  1. DZone
  2. Coding
  3. Java
  4. Building a Samlple Java WebSocket Client

Building a Samlple Java WebSocket Client

Learn more about creating Java-based WebSocket clients, including code for the server side WebSocket application and the corresponding JavaScript/HTML client.

By 
Ulas Ergin user avatar
Ulas Ergin
·
Jan. 08, 14 · Tutorial
Likes (10)
Comment
Save
Tweet
Share
223.8K Views

Join the DZone community and get the full member experience.

Join For Free

Java-Based WebSocket Client Implementation

During my Google search for a Java WebSocket client, I ended up with valuable info on several blogs and presentation slides. Generally, the samples are on the implementation of a server side WebSocket application, but the client side is JavaScript/HTML.  

In this article, I will present a Java based WebSocket client, but for the sake of completeness I will also provide the code for the server side WebSocket application [and the corresponding JavaScript/HTML client as a bonus.

Configuration

Please note the 4 key-points for configuring both the server-side and the client-side.

  1. For the WebSocket server implementation: Java API for WebSocket (JSR-356) is a new standard coming in JavaEE 7, so check your application server support for JavaEE7 on running the WebSocket server sample.

    I generally use WebSphere, but the WAS Liberty 8.5.5 did not run this since it is JavaEE 6 so I ran the server on GlassFish 4.0 (build 89).

    Just deploy the single class provided in a WAR or EAR file. No need to configure the web.xml/deployment descriptor since the annotation based approach is used.


  2. For the Java client implementation: JavaSE7 does not include WebSocket so you should add the necessary jar files yourself.

    I used Tyrus as the WebSocket API implementation.
      Use javax.websocket-api.jar and tyrus-standalone-client-1.3.3.jar from https://tyrus.java.net/

  3. For the Java client implementation: The Java client should have a file named javax.websocket.ContainerProvider in the MEFA-INF/services folder with the content org.glassfish.tyrus.client.ClientManager to introduce Tyrus to the JavaSE7 environment as a WebSocketContainer provider. (see ServiceLoader API for details)

  4. For the JavaScript/HTML bonus implementation: IE9 does not support WebSocket. IE version must be at least 10. For Firefox and Chrome...they have been supporting WebSocket for a very long time so it won't be a problem. See http://caniuse.com for more info

The Application

The sample WebSocket server application is a virtual USD Exchange rate publishing server. A new exchange rate becomes available every 2 seconds and it is published to all registered clients.

 The WebSocket client consumes the new USD rate immediately as it becomes available.

The Server Side

In order to keep things simple and easy to copy and organize in your IDE, the server application is a provided as a single class. This single class contains an anonymous inner class which serves as the Thread to generate and publish the new USD rate every 2 seconds, and the class itself does the WebSocket 'magic' .

package websocket.server;

import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.*;
import javax.websocket.*;
import javax.websocket.server.*;

@ServerEndpoint("/ratesrv")
public class CustomEndPoint {
 //queue holds the list of connected clients
 private static Queue<Session> queue = new ConcurrentLinkedQueue<Session>();
 private static Thread rateThread ; //rate publisher thread

 static
 {
//rate publisher thread, generates a new value for USD rate every 2 seconds.
  rateThread=new Thread(){
   public void run() {
    DecimalFormat df = new DecimalFormat("#.####");
    while(true)
    {
     double d=2+Math.random();     
     if(queue!=null)
      sendAll("USD Rate: "+df.format(d));    
     try {
      sleep(2000);
     } catch (InterruptedException e) {      
     }
    }
   };
  } ;
  rateThread.start();
 }

 @OnMessage
 public void onMessage(Session session, String msg) {
//provided for completeness, in out scenario clients don't send any msg.
  try {   
   System.out.println("received msg "+msg+" from "+session.getId());
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

@OnOpen
 public void open(Session session) {
  queue.add(session);
  System.out.println("New session opened: "+session.getId());
 }

  @OnError
 public void error(Session session, Throwable t) {
  queue.remove(session);
  System.err.println("Error on session "+session.getId());  
 }

 @OnClose
 public void closedConnection(Session session) { 
  queue.remove(session);
  System.out.println("session closed: "+session.getId());
 }

 private static void sendAll(String msg) {
  try {
   /* Send the new rate to all open WebSocket sessions */  
   ArrayList<Session > closedSessions= new ArrayList<>();
   for (Session session : queue) {
    if(!session.isOpen())
    {
     System.err.println("Closed session: "+session.getId());
     closedSessions.add(session);
    }
    else
    {
 session.getBasicRemote().sendText(msg);
    }    
   }
   queue.removeAll(closedSessions);
   System.out.println("Sending "+msg+" to "+queue.size()+" clients");
  } catch (Throwable e) {
   e.printStackTrace();
  }
 }
}

The long promised Java based client implementation

The client application connects to the websocket server and consumes new USD rates.

package websocket.client;

import java.net.URI;
import javax.websocket.*;

@ClientEndpoint
public class WSClient  {
    private static Object waitLock = new Object();

@OnMessage
    public void onMessage(String message) {
//the new USD rate arrives from the websocket server side.
       System.out.println("Received msg: "+message);        
    }

 private static void  wait4TerminateSignal()
 {
  synchronized(waitLock)
  {try {
    waitLock.wait();
   } catch (InterruptedException e) {    
   }}}

public static void main(String[] args) {
WebSocketContainer container=null;//
     Session session=null;
  try{
   //Tyrus is plugged via ServiceLoader API. See notes above
   container = ContainerProvider.getWebSocketContainer(); 

//WS1 is the context-root of my web.app 
//ratesrv is the  path given in the ServerEndPoint annotation on server implementation
session=container.connectToServer(WSClient.class, URI.create("ws://localhost:8080/WS1/ratesrv")); 

   wait4TerminateSignal();
  } catch (Exception e) {
   e.printStackTrace();
  }
  finally{
   if(session!=null){
    try {
 session.close();
    } catch (Exception e) {     
     e.printStackTrace();
    }
   }         
  } 
 }
}


The JavaScript client

The bonus:)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WebSocket Client</title>
 <script type="text/javascript">

      var wsocket;      
      function connect() {         
 wsocket = new WebSocket("ws://localhost:8080/WS1/ratesrv");       
          wsocket.onmessage = onMessage;          
      }

      function onMessage(evt) {             
         document.getElementById("rate").innerHTML=evt.data;          
      }

 window.addEventListener("load", connect, false);
  </script>
</head>
<body>

<table>
<tr>
<td> <label id="rateLbl">Current Rate:</label></td>
<td> <label id="rate">0</label></td>
</tr>
</table>
</body>
</html>




WebSocket Java (programming language)

Published at DZone with permission of Ulas Ergin. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Jakarta WebSocket Essentials: A Guide to Full-Duplex Communication in Java
  • Full-Duplex Scalable Client-Server Communication with WebSockets and Spring Boot (Part I)
  • Beyond Linguistics: Real-Time Domain Event Mapping with WebSocket and Spring Boot
  • Recurrent Workflows With Cloud Native Dapr Jobs

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!