SpringBoot学习笔记(11):使用WebSocket构建交互式Web应用程序
SpringBoot学习笔记(11):使用WebSocket构建交互式Web应用程序
快速开始
本指南将引导您完成创建“hello world”应用程序的过程,该应用程序在浏览器和服务器之间来回发送消息。 WebSocket是一个非常薄,轻量级的TCP层。它使得非常适合使用“子协议”来嵌入消息。在本指南中,我们将深入研究并使用Spring的STOMP消息来创建交互式Web应用程序。
我们将建立一个服务用来接收一个携有用户名称的消息,然后作为回应,推送一个问候语到客户订阅的队列中。
本节内容的思维导图大致如下:

参考教程:
https://spring.io/guides/gs/messaging-stomp-websocket/
STOMP消息
STOMP即Simple (or Streaming) Text Orientated Messaging Protocol,简单(流)文本定向消息协议,它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消息代理(Broker)进行交互。STOMP协议由于设计简单,易于开发客户端,因此在多种语言和多种平台上得到广泛地应用。
STOMP协议的前身是TTMP协议(一个简单的基于文本的协议),专为消息中间件设计。
STOMP是一个非常简单和容易实现的协议,其设计灵感源自于HTTP的简单性。尽管STOMP协议在服务器端的实现可能有一定的难度,但客户端的实现却很容易。例如,可以使用Telnet登录到任何的STOMP代理,并与STOMP代理进行交互。
STOMP协议与2012年10月22日发布了最新的STOMP 1.2规范。
要查看STOMP 1.2规范,见: https://stomp.github.io/stomp-specification-1.2.html
基于Maven构建应用
首先,设置一个基本的构建脚本。在使用Spring构建应用程序时,您可以使用任何您喜欢的构建系统,但此处包含了使用Maven所需的代码。
如果您不熟悉Maven,请参阅使用Maven构建Java项目。
<!--添加WebSocket依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency> <dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</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>
创建一个资源表示类
现在您已经设置了项目和构建系统,您可以创建STOMP消息服务。通过考虑服务交互来开始这个过程。
该服务将接受一个包含在STOMP消息中name的消息,该消息的主体是JSON对象。如果给出的名称是“Fred”,那么消息可能如下所示:
{
"name": "Fred"
}
要对带有name的消息建模,可以使用name属性和相应的getName()方法创建一个普通的Java对象:
public class HelloMessage {
private String name;
public HelloMessage(String name){
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在接收到消息并提取名称后,服务将通过创建问候语并在客户端订阅的单独队列上发布该问候语来处理它。问候语也将是一个JSON对象,可能看起来像这样:
public class GreetingMessage {
private String context;
public GreetingMessage(String context) {
this.context = context;
}
public String getContext() {
return context;
}
public void setContext(String context) {
this.context = context;
}
}
Spring将使用Jackson JSON库自动封送以上类型为JSON的实例。接下来,您将创建一个控制器来接收问候消息并发送问候消息。
创建一个消息处理控制器
import com.mrsaber.filebar.domain.GreetingMessage;
import com.mrsaber.filebar.domain.HelloMessage;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller; @Controller
public class GreetController { @MessageMapping("/hello")
@SendTo("/topic/greetings")
public GreetingMessage greeting(HelloMessage message) throws Exception
{
Thread.sleep(1000);
return new GreetingMessage("Hello,"+message.getName());
}
}
这个控制器看起来是简洁又简单的,但是已经做了大量的工作。让我们来分解一下这个操作。
- @MessageMapping注解确保如果将消息发送到目标“/ hello”,则调用greeting()方法。
- 消息的原数据绑定到HelloMessage对象,该对象将传递给greeting()。
- 在内部,该方法的实现通过使线程休眠1秒来模拟处理延迟。这是为了演示客户端发送消息后,只要需要异步处理消息,服务器就可以使用。客户可以继续进行它需要做的任何工作而无需等待响应。
- 在1秒延迟之后,greeting()方法创建一个Greeting对象并返回它。返回值将广播给@SendTo注解中指定的“/ topic / greetings”的所有订阅者。
配置Spring以进行STOMP消息传递
现在已经创建了服务的基本组件,您可以配置Spring以启用WebSocket和STOMP消息传递。
创建一个名为WebSocketConfig的Java类,如下所示:

创建浏览器客户端
HTML部分
<!DOCTYPE html>
<html>
<head>
<title>Hello WebSocket</title>
<link href="webs/bootstrap.min.css" rel="stylesheet">
<script src="webs/jquery.min.js"></script>
<script src="webs/sockjs.min.js"></script>
<script src="webs/stomp.min.js"></script>
<script src="webs/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" class="btn btn-default" type="submit">Connect</button>
<button id="disconnect" class="btn btn-default" 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" class="btn btn-default" 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="greetings">
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
JavaScript部分
我们编写了一个app.js文件用来存放我们的业务逻辑。
var stompClient = null;
function setConnected(connected) {
$("#connect").prop("disabled", connected);
$("#disconnect").prop("disabled", !connected);
if (connected) {
$("#conversation").show();
}
else {
$("#conversation").hide();
}
$("#greetings").html("");
}
function connect() {
var socket = new SockJS('localhost:8080/gs-guide-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function (greeting) {
showGreeting(JSON.parse(greeting.body).context);
});
});
}
function disconnect() {
if (stompClient !== null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function sendName() {
stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
}
function showGreeting(message) {
$("#greetings").append("<tr><td>" + message + "</td></tr>");
}
$(function () {
$("form").on('submit', function (e) {
e.preventDefault();
});
$( "#connect" ).click(function() { connect(); });
$( "#disconnect" ).click(function() { disconnect(); });
$( "#send" ).click(function() { sendName(); });
});
测试程序

SpringBoot学习笔记(11):使用WebSocket构建交互式Web应用程序的更多相关文章
- SpringBoot学习笔记(一)——构建springboot项目
生成一个SpringBoot的项目 开发和学习SpringBoot需要一个生成好的SpringBoot项目. 1.可以使用一些IDE(Integrated Development Environmen ...
- SpringBoot学习笔记(11)-----SpringBoot中使用rabbitmq,activemq消息队列和rest服务的调用
1. activemq 首先引入依赖 pom.xml文件 <dependency> <groupId>org.springframework.boot</groupId& ...
- Spring boot 官网学习笔记 - 开发第一个Spring boot web应用程序(使用mvn执行、使用jar执行)
Creating the POM <?xml version="1.0" encoding="UTF-8"?> <project xmlns= ...
- SpringBoot学习笔记(14):使用SpringBootAdmin管理监控你的应用
SpringBoot学习笔记(14):使用SpringBootAdmin管理监控你的应用 Spring Boot Admin是一个管理和监控Spring Boot应用程序的应用程序.本文参考文档: 官 ...
- SpringBoot学习笔记(2):引入Spring Security
SpringBoot学习笔记(2):用Spring Security来保护你的应用 快速开始 本指南将引导您完成使用受Spring Security保护的资源创建简单Web应用程序的过程. 参考资料: ...
- SpringBoot学习笔记(10):使用MongoDB来访问数据
SpringBoot学习笔记(10):使用MongoDB来访问数据 快速开始 本指南将引导您完成使用Spring Data MongoDB构建应用程序的过程,该应用程序将数据存储在MongoDB(基于 ...
- springboot学习笔记:9.springboot+mybatis+通用mapper+多数据源
本文承接上一篇文章:springboot学习笔记:8. springboot+druid+mysql+mybatis+通用mapper+pagehelper+mybatis-generator+fre ...
- Spring 源码学习笔记11——Spring事务
Spring 源码学习笔记11--Spring事务 Spring事务是基于Spring Aop的扩展 AOP的知识参见<Spring 源码学习笔记10--Spring AOP> 图片参考了 ...
- Ext.Net学习笔记11:Ext.Net GridPanel的用法
Ext.Net学习笔记11:Ext.Net GridPanel的用法 GridPanel是用来显示数据的表格,与ASP.NET中的GridView类似. GridPanel用法 直接看代码: < ...
随机推荐
- SVN环境搭建详解
SVN服务器搭建和使用(一) Subversion是优秀的版本控制工具,其具体的的优点和详细介绍,这里就不再多说. 首先来下载和搭建SVN服务器. 现在Subversion已经迁移到apache网 ...
- Dicom Conformance
Platform Compatibility of DICOM Transfer Syntax 1.2.840.10008.1.2 Implicit VR - Little Endian yes ...
- Spark sql读取数据库和ES数据进行处理代码
读取数据库数据和ElasticSearch数据进行连接处理 import java.util.HashMap; import java.util.List; import java.util.Map; ...
- 【前端阅读】——《JavaScript应用开发技术详解指南》摘记&思维导图
读这本书,我主要关注三个部分:JavaScript内置函数,程序调试以及Ajax基础.由于多是介绍基本概念,所以,采用思维导图的方式,做了一个梳理,以下就是精简的主要内容. 注:转载请注明出处
- MySQL触发器 trigger学习
触发器:一类特殊的事物.可监视某种数据操作,并触发相关操作(insert/update/delete).表中的某些数据改变,希望同一时候能够引起其他相关数据改变的需求. 作用:变化自己主动完毕某些语句 ...
- Direct-X学习笔记--纹理映射
一.介绍 之前学习了如何绘制物体,还画了个DX自带的茶壶,然而这个东东并不怎么好看....离我们现实的物体简直相隔千里. 仅仅能说像美术他们用来写生的模型...那么要怎么样才干让我们的东西看起来更像真 ...
- xshell容易断开的问题
修改服务器的sshd_config文件. http://bbs.51cto.com/thread-904289-1.html
- appium在MAC上环境搭建
1. 安装.启动Appium bixiaopeng@bixiaopeng ~$ npm install -g appium Password: npm http GET https://registr ...
- 解决:cannot execute binary file
linux系统下遇到cannot execute binary file的问题,一般由以下情况造成: 非root用户或者无执行权限 编译环境不同(程序由其他操作环境复制过来) 对于第一种情况,采用增加 ...
- 3、C++新的关键字
C++ 添加了一些全新的关键字. 1.new new 来进行动态内存的分配,而delect 则是进行内存的释放, 申请的方式: 变量申请: int *p = new int; // 申 ...