WebSocket แบบง่ายๆ ด้วย Spring Boot

ตัวอย่างนี้เราจะสร้าง WebSocket แบบง่ายๆ โดยใช้ Spring Boot กันนะครับ
สามารถดาวน์โหลด Source code ได้ที่ https://bitbucket.org/zengcode/websocket

เนื่องจาก มี Source ให้ดาวน์โหลดแล้วบทความนี้จะขออธิบายแบบคร่าวๆ นะครับ
โจทย์ : ให้ Server ส่ง เวลา ปัจจุบันให้ Client แสดงทุกๆ 1 วินาที โดยใช้ WebSocket เอาแบบง่ายๆ เลยครับ

ตัวอย่างโปรเจคส์นี้เป็น Maven Project นะครับ ดังนั้นเริ่มต้นเรามาสร้าง pom.xml กันก่อนครับ

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>4.0.0</modelVersion>

<groupId>websocket.zencode.com</groupId>
<artifactId>websocket</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>sockjs-client</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>stomp-websocket</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.1.0</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

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

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

ต่อไปสร้าง Configuration เพื่อ register endpoint ที่เชื่อว่า /zengcode-websocket และ enable a simple memory-based message broker ที่ชื่อว่า /topic สำหรับส่ง message กลับไปให้ client นะครับ


@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/zengcode-websocket").withSockJS();
}

}

ต่อไปสร้าง object PayLoad ที่เป็น plain old Java object ให้มี contentproperty และ method getContent() สำหรับส่งข้อความกลับไปให้ client

public class Payload {

private String content;

public Payload() {
}

public Payload(String content) {
this.content = content;
}

public String getContent() {
return content;
}
}

ต่อไปมาสร้าง Scheduler Task สำหรับส่งเวลากลับไปให้ Client ทุกๆ 1 วินาที

@Component
public class SchedulerTask {

private SimpMessagingTemplate template;

@Autowired
public SchedulerTask(SimpMessagingTemplate template) {
this.template = template;
}

private static SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

@Scheduled(fixedRate = 1000)
public void sendMessageToClient() {

this.template.convertAndSend("/topic/greetings", new Payload("Time is : " + dateFormat.format(new Date()) ));
}


}

แล้วใน Class ของ Application ให้ enable scheduling นะครับ

@SpringBootApplication
@EnableScheduling
public class WebSocketApplication {

public static void main(String[] args) {
SpringApplication.run(WebSocketApplication.class, args);
}
}

ต่อไปเป็นส่วนของ Client กันแล้วนะครับ สร้างหน้าเพจขึ้นมาครับ src/main/resources/static/index.html

<!DOCTYPE html>
<html>
<head>
<title>Hello WebSocket</title>
<link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="/main.css" rel="stylesheet">
<script src="/webjars/jquery/jquery.min.js"></script>
<script src="/webjars/sockjs-client/sockjs.min.js"></script>
<script src="/webjars/stomp-websocket/stomp.min.js"></script>
<script src="/app.js"></script>
<script>
connect();
</script>
</head>
<body>
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being
enabled. Please enable
Javascript and reload this page!</h2></noscript>
<div id="main-content" class="container">
<div class="row">
<div class="col-md-6">
<h3>ZengCode : WebSocket Example</h3>
</div>
</div>
<div class="row">
<div class="col-md-12">
<table id="conversation" class="table table-striped">
<thead>
<tr>
<th>&nbsp;</th>
</tr>
</thead>
<tbody id="greetings">
</tbody>
</table>
</div>
</div>
</form>
</div>
</body>
</html>

HTML file ตัวนี้จะ imports SockJS และ STOMP javascript libraries ซึ่งจะใช้ใน STOMP over websocket. สร้าง app.js ใน src/main/resources/static/app.js

var stompClient = null;


function connect() {
var socket = new SockJS('/zengcode-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function (message) {
showGreeting(JSON.parse(message.body).content);
});
});
}

function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}


function showGreeting(message) {
$("#greetings").html("<br/><b>" + message + "</b>");
}

ก็เป็นอันเสร็จพิธีครับ เมื่อรัน application แล้วเปิด browser ขึ้นมา
Server จะส่ง เวลา ปัจจุบันมาให้ Client update ทุกๆ 1 วินาที ดังรูปข้างล่างนี้ครับ

ง่ายๆ นะครับ เอาไป apply ใช้กับงานที่ต้องการต่อไปนะครับ

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.