一、目录结构
目录结构
二、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>com.airkisser</groupId>
<artifactId>spring-boot-sample-websocket</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>spring-boot-sample-websocket</name>
<description>Spring boot websocket sample</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.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-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</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>
三、application.properties
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode=HTML5
spring.thymeleaf.content-type=text/html
# 开启 thymeleaf 热部署
spring.thymeleaf.cache=false
四、java
Application.java
package com.airkisser;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
WebSocketConfig.java
package com.airkisser.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
@Configuration
// 该注解开启使用STOMP协议来传输基于代理(message broker)的消息,
// 此时控制器支持使用@MessageMapping
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override// 注册STOMP协议的节点(endpoint),并映射指定的URL
public void registerStompEndpoints(StompEndpointRegistry registry) {
// 注册一个STOMP的endpoint,并指定使用SockJS协议
registry.addEndpoint("endpointAir").withSockJS();
}
@Override// 配置消息代理(Message Broker)
public void configureMessageBroker(MessageBrokerRegistry registry) {
// 配置一个广播式消息代理:"/topic"
registry.enableSimpleBroker("/topic");
}
}
WebMvcConfig.java
package com.airkisser.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("welcome");
}
}
Message.java
package com.airkisser.entity;
import java.io.Serializable;
public class Message implements Serializable {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
Response.java
package com.airkisser.entity;
import java.io.Serializable;
public class Response implements Serializable {
private String message;
public Response(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
WebSocketController.java
package com.airkisser.web;
import com.airkisser.entity.Message;
import com.airkisser.entity.Response;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
@Controller
public class WebSocketController {
@MessageMapping("/welcome")
@SendTo("/topic/getResponse")
public Response welcome(Message message) {
return new Response("Message: " + message.getMessage());
}
}
五、welcome.html
<!DOCTYPE html>
<html lang="zh_CN" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>Spring Boot WebSocket广播式</title>
</head>
<body>
<div>
<div>
<button id="connect">连接</button>
<button id="disconnect">断开连接</button>
</div>
<div id="sendDiv">
<label for="message">信息</label>
<input type="text" id="message"/>
<button id="send">发送</button>
</div>
<div id="response">
</div>
</div>
<script th:src="@{/js/jquery.js}"></script>
<script th:src="@{/js/stomp.js}"></script>
<script th:src="@{/js/sockjs.js}"></script>
<script>
$(document).ready(function () {
var stompClient;
$('#sendDiv').hide();
$('#response').hide();
$('#disconnect').attr('disabled', true);
$('#connect').click(function () {
connect();
});
$('#disconnect').click(function () {
disconnect();
});
$('#send').click(function () {
sendMessage();
});
function connect() {
// 指定连接SockJS的endpoint名称为"/endpointAir"
var socket = new SockJS('/endpointAir');
// 使用STOMP子协议
stompClient = Stomp.over(socket);
// 连接WebSocket服务端
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
// 订阅目标"/topic/getResponse"发送的消息
stompClient.subscribe('/topic/getResponse', function (response) {
showResponse(JSON.parse(response.body).message)
});
});
}
function disconnect() {
// 断开连接
if (stompClient) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function sendMessage() {
// 向目标"/welcome"发送消息
stompClient.send('/welcome', {}, JSON.stringify({'message': $('#message').val()}));
}
function showResponse(message) {
$('#response').append("<p>" + message + "</p>");
}
function setConnected(connected) {
if (connected) {
$('#sendDiv').show();
$('#response').show();
} else {
$('#sendDiv').hide().find('input').val('');
$('#response').html('').hide();
}
$('#connect').attr('disabled', connected);
$('#disconnect').attr('disabled', !connected);
}
});
</script>
</body>
</html>
六、结果
RUN
网友评论