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
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
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

Integrating PostgreSQL Databases with ANF: Join this workshop to learn how to create a PostgreSQL server using Instaclustr’s managed service

Mobile Database Essentials: Assess data needs, storage requirements, and more when leveraging databases for cloud and edge applications.

Monitoring and Observability for LLMs: Datadog and Google Cloud discuss how to achieve optimal AI model performance.

Automated Testing: The latest on architecture, TDD, and the benefits of AI and low-code tools.

Related

  • Getting Started With JMS-ActiveMQ: Explained in a Simple Way
  • MicroProfile: What You Need to Know
  • How To Validate Archives and Identify Invalid Documents in Java
  • How To Check Office Files for Macros Using Java

Trending

  • Memory Management in Java: An Introduction
  • Anomaly Detection: Leveraging Rule Engines to Minimize False Alarms
  • DevSecOps: Integrating Security Into Your DevOps Workflow
  • How To Use ChatGPT API in Python for Your Real-Time Data
  1. DZone
  2. Coding
  3. Java
  4. WebSocket Client API in Java EE 7

WebSocket Client API in Java EE 7

Did you know that there's a little used Web Socket client side API for Java?

Abhishek Gupta user avatar by
Abhishek Gupta
CORE ·
Jul. 21, 15 · Tutorial
Like (1)
Save
Tweet
Share
10.16K Views

Join the DZone community and get the full member experience.

Join For Free

In this post, let’s explore the less talked about Web Socket Client API and how to leverage it within a Java EE 7 container itself

Web Socket Server API rules

The server side API of JSR 356 (Web Socket API for Java) is most commonly used for building Web Socket endpoint implementations. More often than not, from a client perspective, the standard JavaScript Web Socket API is leveraged by the HTML5 (browser) based clients which attach themselves to web socket server end points and enjoy bi-directional and full-duplex communication. You would have seen common examples such applications such as live maps, stock tickers, games, screen sharing etc – all these use cases are perfect for Web Sockets and Java EE 7 is the ideal platform for building scalable Web Socket driven back end.

What about the Web Socket client side API ?

The Web Socket specification includes a client side API as well and its mandatory for all JSR 356 (e.g. Tyrus, Undertow etc) implementations to provide one. There are quite a few use cases wherein a browser based / end user facing web socket client might not be required.

Example

Consider a scenario where you want to connect to a third party Web Socket end point, consume it’s information and persist it for later use ? Maybe for further analysis ? In such cases, its useful to leverage the client API within the Java EE container itself.

Let’s explore this with a simple example.

(annotated) Web Socket Client

Note: the logic for @OnMessage was excluded on purpose and has been implemented in a different way (clarified later)

package blog.abhirockzz.wordpress.com;

import javax.websocket.ClientEndpoint;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.Session;

@ClientEndpoint
public class StockTickerClient {

    @OnClose
    public void closed(Session session) {
        System.out.println("Session " + session + " closed");

    }

    @OnError
    public void error(Throwable error) {
        System.out.println("Error: " + error.getMessage());

    }

}


A Stock Ticker (info) JPA entity

package blog.abhirockzz.wordpress.com;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "STOCK_TICK")
public class StockTick implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;
    private String price;

    public StockTick(String name, String price) {
        this.name = name;
        this.price = price;
    }

    public StockTick() {
        //for JPA
    }

    //getters and setters omitted ...
}


A Stateless bean

  • Handles persistence of Stock Ticker info
  • Executes its operations against the default JDBC data source provided by the Java EE 7 container (convention over configuration in action!)
package blog.abhirockzz.wordpress.com;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class StockInfoPersistenceService {

    @PersistenceContext
    EntityManager em;

    public void save(String name, String price){
        em.persist(new StockTick(name, price));
    }
}


Singleton EJB

  • Leverages the Web Socket ContainerProvider API
  • Initiates the connection to a web socket server
  • Injects the StockInfoPersistenceService bean and uses it within the addMessageHandler implementation

As per previous note, the (persistence) logic which could have been embedded in a @OnMessage annotated method within the StockTickerClient class has been included here. This is because the injection of the StockInfoPersistenceService (stateless) bean was failing and the instance itself was being resolved to null.

package blog.abhirockzz.wordpress.com;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.inject.Inject;
import javax.websocket.ContainerProvider;
import javax.websocket.DeploymentException;
import javax.websocket.MessageHandler;
import javax.websocket.Session;
import javax.websocket.WebSocketContainer;

@Singleton
@Startup
public class StockServiceBootstrapBean {

    private final String WS_SERVER_URL = "ws://api.stocks/ticker"; //fictitious
    private Session session = null;

    @Inject
    StockInfoPersistenceService tickRepo;

    @PostConstruct
    public void bootstrap() {
        WebSocketContainer webSocketContainer = null;
        try {
            webSocketContainer = ContainerProvider.getWebSocketContainer();
            session = webSocketContainer.connectToServer(StockTickerClient.class, new URI(WS_SERVER_URL));

            System.out.println("Connected to WS endpoint " + WS_SERVER_URL);
            session.addMessageHandler(new MessageHandler.Whole<String>() {

                @Override
                public void onMessage(String msg) {
                    tickRepo.save(msg.split(":")[0], msg.split(":")[1]);
                }
            });
        } catch (DeploymentException | IOException | URISyntaxException ex) {
            Logger.getLogger(StockServiceBootstrapBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @PreDestroy
    public void destroy() {
        close();
    }

    private void close() {
        try {
            session.close();
            System.out.println("CLOSED Connection to WS endpoint " + WS_SERVER_URL);
        } catch (IOException ex) {
            Logger.getLogger(StockServiceBootstrapBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}


That’s pretty much it. Although this was a relatively simple example, its not too hard to imagine that one can apply any sort of complex business logic on the information received by the web socket server endpoint. You might also want to think about sending messages to connected clients in an asynchronous fashion using the session.getAsyncRemote#sendAsync method

API Java EE Java (programming language) WebSocket

Published at DZone with permission of Abhishek Gupta, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Getting Started With JMS-ActiveMQ: Explained in a Simple Way
  • MicroProfile: What You Need to Know
  • How To Validate Archives and Identify Invalid Documents in Java
  • How To Check Office Files for Macros Using Java

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • 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: