livesdmo.com

Building a Real-Time Crypto Price Simulator with Spring Boot

Written on

Chapter 1: Introduction to the Crypto Price Simulator

In this article, we will develop a Crypto Price Simulator that consists of two distinct Spring Boot applications: the Crypto Price Producer and the Crypto Price Consumer. The Producer generates updates for cryptocurrency prices, with a focus on Bitcoin (BTC), and broadcasts these updates via WebSocket. Meanwhile, the Consumer connects to the Producer's WebSocket to receive and process the price changes.

If you're interested in creating a React Consumer for this Crypto Price Simulator, check out:

Real-time Crypto Price Simulator: Implementing a React Consumer App

Step-by-step guide to building a React App that consumes real-time updates from the Spring Boot Producer's WebSocket.

For those looking to run the Crypto Price Simulator on Minikube (Kubernetes), we provide detailed instructions here:

Real-time Crypto Price Simulator: Running in Minikube (Kubernetes)

Exploring how to deploy the Crypto Price Producer, Consumer, and WebSocket functionality in a Kubernetes environment.

Now, let’s get started!

WebSocket, SockJS, and STOMP Overview

This article delves into more than just WebSocket; it also incorporates SockJS and STOMP. Together, these three components create a powerful framework for real-time web communication.

Here’s a brief overview of each:

  • WebSocket: A protocol that facilitates full-duplex communication between a client and a server over a single, persistent connection, enabling real-time data exchange.
  • SockJS: Functions as both a JavaScript library and a protocol. As a library, it abstracts WebSocket for a consistent API experience, while as a protocol, it sets communication rules and fallback options for environments lacking robust WebSocket support.
  • STOMP (Simple Text Oriented Messaging Protocol): A lightweight messaging protocol designed for the WebSocket architecture. STOMP provides a higher-level abstraction over WebSocket, featuring capabilities like message routing, publish-subscribe models, and point-to-point communication.

Prerequisites

To follow along with this tutorial, ensure you have Java 17 or higher installed on your machine.

Creating the Project Structure

  1. Create a Directory: Set up a folder named websocket-crypto-simulator in your workspace where we will develop the Producer and Consumer applications.

Creating the Crypto Price Producer Spring Boot Application

We will initiate our Spring Boot application using Spring Initializr. Name the application crypto-price-producer and include the following dependencies: Spring Web and WebSocket. We will utilize Spring Boot version 3.2.4 with Java 17. Follow this [link](#) for all setup details.

After clicking the GENERATE button, download the zip file, extract it into the websocket-crypto-simulator folder, and open the crypto-price-producer project in your IDE.

Organizing Code with Packages

To maintain an organized code structure, create the following packages within the com.example.cryptopriceproducer root package: simulator and websocket.

Defining the CryptoUpdate Record

In the simulator package, define the CryptoUpdate record with the following code:

package com.example.cryptopriceproducer.simulator;

public record CryptoUpdate(String crypto, String price, String datetime) {

}

This record encapsulates the data sent through the WebSocket.

Implementing the CryptoSimulator Class

Next, in the simulator package, create the CryptoSimulator class with the provided implementation:

package com.example.cryptopriceproducer.simulator;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.messaging.simp.SimpMessagingTemplate;

import org.springframework.scheduling.annotation.EnableScheduling;

import org.springframework.scheduling.annotation.Scheduled;

import org.springframework.stereotype.Component;

import java.security.SecureRandom;

import java.text.NumberFormat;

import java.time.Instant;

import java.time.ZoneId;

import java.time.format.DateTimeFormatter;

import java.util.Locale;

import java.util.Random;

@EnableScheduling

@Component

public class CryptoSimulator {

private final SimpMessagingTemplate simpMessagingTemplate;

public CryptoSimulator(SimpMessagingTemplate simpMessagingTemplate) {

this.simpMessagingTemplate = simpMessagingTemplate;

}

@Scheduled(fixedRate = 1000)

public void simulateTrade() {

if (hasTrade()) {

double price = rand.nextDouble() * 100;

String priceInDollar = priceFormatter.format(price);

String dateTimeFormatted = dateTimeFormatter.format(Instant.now());

CryptoUpdate cryptoUpdate = new CryptoUpdate("BTC", priceInDollar, dateTimeFormatted);

log.info("Publishing crypto change: {}", cryptoUpdate);

simpMessagingTemplate.convertAndSend("/topic/prices", cryptoUpdate);

}

}

private boolean hasTrade() {

return rand.nextBoolean();

}

private static final Logger log = LoggerFactory.getLogger(CryptoSimulator.class);

private static final Random rand = new SecureRandom();

private static final NumberFormat priceFormatter = NumberFormat.getCurrencyInstance(Locale.US);

private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")

.withZone(ZoneId.systemDefault());

}

This class simulates updates in crypto prices and publishes them to a WebSocket topic. The simulateTrade() method runs every second, and the hasTrade() method determines whether a trade occurred. It constructs CryptoUpdate objects with random prices and sends them to the /topic/prices destination.

Configuring WebSocket with WebSocketConfig Class

In the websocket package, create the WebSocketConfig class with the following content:

package com.example.cryptopriceproducer.websocket;

import org.springframework.context.annotation.Configuration;

import org.springframework.messaging.simp.config.MessageBrokerRegistry;

import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;

import org.springframework.web.socket.config.annotation.StompEndpointRegistry;

import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration

@EnableWebSocketMessageBroker

public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

@Override

public void registerStompEndpoints(StompEndpointRegistry registry) {

registry.addEndpoint("/ws")

.setAllowedOriginPatterns("*")

.withSockJS();

}

@Override

public void configureMessageBroker(MessageBrokerRegistry registry) {

registry.setApplicationDestinationPrefixes("/app");

registry.enableSimpleBroker("/topic");

}

}

This class sets up WebSocket configurations. The @EnableWebSocketMessageBroker annotation enables WebSocket message handling, including higher-level messaging protocols.

Creating the Crypto Price Consumer Spring Boot Application

Now, we will create another Spring Boot application using Spring Initializr, naming it crypto-price-consumer. Include the dependencies: Spring Web and Thymeleaf, using the same version settings as before.

Creating app.js

Within the src/main/resources/static directory, create the app.js file with the following content:

function connectToWebSocket(uri) {

const url = uri + "/ws";

const socket = new SockJS(url);

const stompClient = Stomp.over(socket);

stompClient.connect({},

function (frame) {

console.log('Connected: ' + frame);

stompClient.subscribe('/topic/prices', function (cryptoUpdate) {

console.log(cryptoUpdate);

const cryptoUpdateBody = JSON.parse(cryptoUpdate.body);

const row = '<tr>' +

'<td>' + cryptoUpdateBody.datetime + '</td>' +

'<td>' + cryptoUpdateBody.crypto + '</td>' +

'<td>' + cryptoUpdateBody.price + '</td>' +

'</tr>';

$('table tbody').prepend(row);

});

},

function() {

alert('Unable to connect to Websocket!');

}

);

}

This JavaScript function establishes a WebSocket connection to a provided URI, subscribing to the /topic/prices topic upon successful connection. It dynamically adds new crypto updates to the HTML table and alerts the user in case of a connection failure.

Creating the index.html File

In the src/main/resources/templates directory, create the index.html file with the following content:

<!DOCTYPE html>

<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head>

<meta charset="UTF-8">

<title>Bitcoin-Client</title>

</head>

<body>

<div class="ui text container">

<h1 class="ui center aligned header">Crypto Price</h1>

<table class="ui compact table">

<thead>

<tr>

<th>Date/Time</th>

<th>Crypto</th>

<th>Price</th>

</tr>

</thead>

<tbody></tbody>

</table>

</div>

</body>

<script src="/app.js"></script>

<script th:inline="javascript">

$(function() {

const uri = "[(${@environment.getProperty('crypto-prices-producer.ws.uri')})]";

connectToWebSocket(uri);

});

</script>

</html>

This HTML document contains a header and a table for displaying crypto update information. The connection to the Crypto Price Producer WebSocket is initiated through a script at the bottom.

Updating application.properties

Modify the application.properties file to include:

server.port=9080

crypto-prices-producer.ws.uri=http://localhost:8080

Here’s a brief explanation of each property:

  • server.port: Defines the application's port.
  • crypto-prices-producer.ws.uri: Specifies the URI for the Crypto Price Producer WebSocket.

Demonstration of the Simulator

To start the Crypto Price Producer and Consumer applications, run the following commands in separate terminal windows:

# For the Producer

./mvnw clean spring-boot:run

# For the Consumer

./mvnw clean spring-boot:run

Visualizing Price Updates

Open your browser and navigate to http://localhost:9080. You should see the crypto price updates:

Crypto Price Updates Visualization

Shutting Down

To stop the applications, press Ctrl+C in the terminal windows where the Crypto Price Producer and Consumer are running.

Conclusion

In this article, we successfully created a Crypto Price Simulator utilizing two Spring Boot applications: the Crypto Price Producer and the Crypto Price Consumer. The Producer simulates price updates for Bitcoin and shares them via WebSocket, while the Consumer connects to track these updates. We concluded with a demonstration of the Crypto Price Simulator in action.

Additional Readings

  • RSocket Crypto Server Tutorial

The video titled "Real-Time Crypto Price using JS and WebSockets | Binance Websocket Market Streams API" provides insights into implementing WebSocket for real-time crypto price updates.

Support and Engagement

If you found this article helpful, consider supporting by:

  • Engaging through claps, highlights, and comments—I’m here to answer any questions you may have.
  • Sharing this article on your social media platforms.
  • Following me on Medium, LinkedIn, Twitter, and GitHub.
  • Subscribing to my newsletter to stay updated with my latest posts.

Share the page:

Twitter Facebook Reddit LinkIn

-----------------------

Recent Post:

Revolutionizing Healthcare: The Breakthrough of Artificial Blood

Japanese researchers have developed artificial blood that can be universally used, potentially transforming emergency medical care.

Can New Universes Be Created Through Black Holes?

Exploring the potential of black holes to generate new universes through mathematical concepts.

Tips for Successfully Integrating a New Habit into Your Life

Explore effective strategies for establishing new habits with insights from holistic health coaching.

# The Transformative Impact of Lifelong Learning on Personal Growth

Explore the transformative nature of lifelong learning, its benefits, and how to overcome challenges to embrace personal growth.

Understanding Abiogenesis and Its Misconceptions in Atheism

A deep dive into the concept of abiogenesis, exploring its implications for atheism and religion while promoting open-minded dialogue.

The Transformative 7-Step Morning Routine That Changed My Life

Discover how a structured morning routine helped me leave my 9-5 job and embrace self-employment full-time.

A Comprehensive Guide to Safeguarding Your Online Privacy

Explore effective strategies for protecting your online privacy and minimizing data footprints in today’s digital age.

Unveiling the Wonders of Complex Functions and Their Applications

Discover the beauty and applications of complex functions in this engaging exploration of complex analysis.