WebSocket + Kotlin + Spring boot simple application example

Hello everyone, Today we will learn how to develop a Simple Kotlin - Spring Boot - WebSocket, chat application.



Why WebSocket?

We already know traditional HTTP requests are unidirectional and heavy. But WebSocket is bi-directional. The initial connection is using HTTP, then this connection gets upgraded to a socket-based connection. This single connection is then used for all future communication. The WebSocket message data exchange is much lighter compared to HTTP.


Project Directory:

Pom.xml[maven]

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.dev</groupId>
<artifactId>kotlin_spring_websocket_example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>kotlin_spring_websocket_example</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
<kotlin.version>1.3.72</kotlin.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.vaadin.external.google</groupId>
<artifactId>android-json</artifactId>
<version>0.0.20131108.vaadin1</version>
<scope>compile</scope>
</dependency>
</dependencies>

<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

</project>

Creating the Socket Configuration

package com.knf.dev.config

import com.knf.dev.handler.TextHandler
import org.springframework.context.annotation.Configuration
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry
import org.springframework.web.socket.config.annotation.WebSocketConfigurer
import org.springframework.web.socket.config.annotation.EnableWebSocket

@Configuration
@EnableWebSocket
class SocketConfig : WebSocketConfigurer {
override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
registry.addHandler(TextHandler(), "/getMessage")
}
}

Creating the Handler

package com.knf.dev.handler

import org.springframework.web.socket.TextMessage
import org.json.JSONException
import org.json.JSONObject
import org.springframework.stereotype.Component
import java.io.IOException
import org.springframework.web.socket.WebSocketSession
import org.springframework.web.socket.handler.TextWebSocketHandler

@Component
class TextHandler : TextWebSocketHandler() {
@Throws(InterruptedException::class, IOException::class, JSONException::class)
public override fun handleTextMessage(session: WebSocketSession, message:
                             TextMessage) {
val payload = message.payload
val jsonObject = JSONObject(payload)
session.sendMessage(TextMessage("Your message:" + jsonObject.get("user")))
}
}

Creating the Main Driver

package com.knf.dev

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class KotlinSpringWebsocketExampleApplication

fun main(args: Array<String>) {
runApplication<KotlinSpringWebsocketExampleApplication>(*args)
}

Creating the view

<!DOCTYPE html>
<html>

<head>
<title>WebSocket Chat Application</title>
<link href="/bootstrap.min.css" rel="stylesheet">
<script src="/jquery.min.js"></script>
<script src="/main.js"></script>
<script src="/bootstrap.min.js"></script>
</head>

<body>
<div class="container">
<br> <br> <br>
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8">
<form class="form-inline">
<div class="form-group">
<label for="connect">Kotlin + Spring Boot socket programming
example:</label>
<button class="btn btn-success" id="connect"
                                                type="button">Start
</button>
<button class="btn btn-danger" id="disconnect"
                                type="button" disabled="disabled">End</button>
</div>
</form>
</div>
<div class="col-md-2"></div>
</div>
<br> <br> <br>
<div class="row">
<div class="col-md-2">
<table id="chat">
<thead>
<tr>
<th>Welcome,Please enter your message</th>
</tr>
</thead>
</table>
</div>
<div class="col-md-2"></div>
<div class="col-md-6">
<form>
<div class="form-group">
<textarea class="form-control" rows="5" id="user"
                               placeholder="Write your message here..."
required></textarea>
</div>
<button class="btn btn-primary" id="send" type="submit">Send</button>
</form>
</div>
<div class="col-md-2"></div>
<br> <br>
</div>
<div class="raw">
<div class="col-md-2">
<table id="response">
<thead>
<tr>
<th>Your Message</th>
</tr>
</thead>
</table>
</div>
<div class="col-md-2"></div>
<div class="col-md-8">
<form>
<div class="form-group">
<textarea id="helloworldmessage" class="form-control"
                        rows="15" placeholder="Your Message"
required></textarea>
</div>
</form>
</div>
</div>
</div>
</body>

</html>

main.js

var ws;
function setConnected(connected) {
$("#connect").prop("disabled", connected);
$("#disconnect").prop("disabled", !connected);
}

function connect() {
ws = new WebSocket('ws://localhost:8080/getMessage');
ws.onmessage = function(data) {
helloWorld(data.data);
}
setConnected(true);
}
function disconnect() {
if (ws != null) {
ws.close();
}
setConnected(false);
console.log("Websocket is in disconnected state");
}
function sendData() {
var data = JSON.stringify({
'user' : $("#user").val()
})
ws.send(data);
}

function helloWorld(message) {
$("#helloworldmessage").append("\n " + message + "");
}

$(function() {
$("form").on('submit', function(e) {
e.preventDefault();
});
$("#connect").click(function() {
connect();
});
$("#disconnect").click(function() {
disconnect();
});
$("#send").click(function() {
sendData();
});
});

Run 

$ mvn spring-boot:run

Download source code

Popular posts from this blog

Learn Java 8 streams with an example - print odd/even numbers from Array and List

Java Stream API - How to convert List of objects to another List of objects using Java streams?

Registration and Login with Spring Boot + Spring Security + Thymeleaf

Java, Spring Boot Mini Project - Library Management System - Download

ReactJS, Spring Boot JWT Authentication Example

Spring Boot + Mockito simple application with 100% code coverage

Top 5 Java ORM tools - 2024

Java - Blowfish Encryption and decryption Example

Spring boot video streaming example-HTML5

Google Cloud Storage + Spring Boot - File Upload, Download, and Delete