網頁

2019/4/28

Spring Boot WebSocket Getting Started example

This article is from official tutorial Using WebSocket to build an interactive web application.


However, there is a little different from the original example, but most are the same.

First, use Spring Tool Suit(STS) to create a Spring Boot project with WebSocket library.


After project created, the default content of pom.xml as below.

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>idv.matt</groupId>
    <artifactId>spring-boot-websocket-getting-started</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-websocket-getting-started</name>
    <description>Spring Boot WebSocket Getting Started</description>

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

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

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

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

</project>


Create the following three java classes.

  • WebSocketConfig.java
  • HelloMessage.java
  • HelloController.java

WebSocketConfig

package idv.matt.demo.config;

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;

@EnableWebSocketMessageBroker
@Configuration
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic");
        registry.setApplicationDestinationPrefixes("/app");
    }
    
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").withSockJS();
    }
    
}

HelloMessage

package idv.matt.demo.message;

public class HelloMessage {

    private String name;

    private String content;

    public HelloMessage() {
    }
    
    public HelloMessage(String name, String content) {
        this.name = name;
        this.content = content;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

}

HelloController

package idv.matt.demo.controller;

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;

import idv.matt.demo.message.HelloMessage;

@Controller
public class HelloController {
    
    private static final int ONE_SECOND = 1000;
    
    @MessageMapping("/hello")
    @SendTo("/topic/hello")
    public HelloMessage hello(HelloMessage message) throws InterruptedException {
        Thread.sleep(ONE_SECOND); // simulated delay
        message.setContent("Hello " + message.getName() + ", WebSocket!!");
        return message;
    }

}

Create a folder named "static" under src/main/resources of the project, and create the following three files in "static" folder.

  • index.html
  • app.js
  • main.css

index.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Hello WebSocket</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.css" rel="stylesheet">
<link href="/main.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.3.0/sockjs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.js"></script>
<script src="/app.js"></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">
                <form class="form-inline">
                    <div class="form-group">
                        <label for="connect">WebSocket
                            connection:</label>
                        <button id="connect" type="button" class="btn btn-primary"
                            type="submit">Connect</button>
                        <button id="disconnect" type="button" class="btn btn-danger"
                            type="submit" disabled="disabled">Disconnect</button>
                    </div>
                </form>
            </div>
            <div class="col-md-6">
                <form class="form-inline">
                    <div class="form-group">
                        <label for="name">What is your name?</label> <input
                            type="text" id="name" class="form-control"
                            placeholder="Your name here...">
                    </div>
                    <button id="send" type="button" class="btn btn-primary"
                        type="submit">Send</button>
                </form>
            </div>
        </div>
        <div class="row">
            <div class="col-md-12">
                <table id="conversation" class="table table-striped">
                    <thead>
                        <tr>
                            <th>Greetings</th>
                        </tr>
                    </thead>
                    <tbody id="hello">
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</body>
</html>

app.js

var stompClient = null;

function setConnected(connected) {
  $("#connect").prop("disabled", connected);
  $("#disconnect").prop("disabled", !connected);
  if (connected) {
    $("#conversation").show();
  } else {
    $("#conversation").hide();
  }
  $("#hello").html("");
}

function connect() {
  var socket = new SockJS('/ws');
  stompClient = Stomp.over(socket);
  stompClient.connect({}, function(frame) {
    setConnected(true);
    console.log('Connected: ' + frame);
    stompClient.subscribe('/topic/hello', function(message) {
      showHello(JSON.parse(message.body).content);
    });
  });
}

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

function sendName() {
  if (stompClient == null) {
    console.log("You haven't connected yet");
  } else {
    stompClient.send("/app/hello", {}, JSON.stringify({
      'name' : $("#name").val()
    }));
  }
}

function showHello(message) {
  $("#hello").append("" + message + "");
}

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

main.css

body {
    background-color: #f5f5f5;
}

#main-content {
    max-width: 940px;
    padding: 2em 3em;
    margin: 0 auto 20px;
    background-color: #fff;
    border: 1px solid #e5e5e5;
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
}

After created all required file, the project structure as below.



Start the project in STS, and enter http://localhost:8080/ in the browser url address bar.

You will see the page as below. Click Connect button first to create a WebSocket connection, then enter your name in the input field at right side, then click Send button to send message to Server via WebSocket.

After one second, you will see the message pop in the bottom area, which is pushed back from Server.

Click Disconnect will stop the WebSocket connection.




沒有留言:

張貼留言