最近看了Spring in Action,了解了一下WebSocket和Stomp协议相关技术,并搭建了一个项目。网上的例子不完整或者描述不清,所以自己记录一下以作备忘。

一.配置

Spring Boot项目搭建完成后,基于Spring Boot一切皆配置的概念,添加WebSocket支持十分简单。

首先是maven依赖:

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

如果是使用的Spring Mvc的话,可能需要添加另外的2个依赖。

然后是添加配置类:WebSocketConfig

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
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry.addEndpoint("/endpointSang").withSockJS();
} @Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/happy");
}
}

其中的两个路径:

1.addEndpoint添加的第一个路径,是监听WebSocket连接的Stomp代理的端点,页面请求WebSocket连接时,连接到注册的该端点上Stomp代理,之后的消息会交给Stomp代理处理。

2.该配置启用了一个简单的消息代理,用来处理前缀为/happy的消息,也就是说,只有路径为/happy请求时,消息才会由消息代理处理

二.后端配置控制器Controller

Controller十分相似,部分注解略有不同:

import com.example.demo.bean.TestMessage;
import com.example.demo.bean.TestResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date; @Controller
public class WsController {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@MessageMapping("/welcome")//接收路径
@SendTo("/happy/getNewResponse")//消息返回到的路径
public TestResponse say(TestMessage message) {
System.out.println(message.getName());
say1();//调用另外的方式返回(由服务器主动发起的返回)
return new TestResponse("welcome," + message.getName() + " !");//这次同步通信的返回
} public void say1() {
Date date =new Date(System.currentTimeMillis());
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(date);
messagingTemplate.convertAndSend("/happy/getHappyResponse", df.format(new Date()));//设置路径以及内容,返回当前服务器时间
}
}
  1. TestMessage与TestResponse为普通JavaBean,消息转换机制等与普通Controller基本一致

  2. SimpMessagingTemplate该类提供为主动向页面正在监听WebSocket的程序发送消息的功能

  3. @MessageMapping注解,与@RequestMapping注解类似,配置后台接收消息的路径以及处理函数

  4. @SendTo注解,一般与@MessageMapping注解一起使用,该注解配置的控制器,返回的数据将发送到监听该配置路径的监听函数

三.前端页面

<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>广播式WebSocket</title>
<script src="../static/jquery.min.js"></script>
<script src="../static/stomp.js"></script>
<script src="../static/sockjs.js"></script>
</head>
<body onload="disconnect()">
<div>
<div>
<button id="connect" onclick="connect();">连接</button>
<button id="disconnect" disabled="disabled" onclick="disconnect();">断开连接</button>
</div> <div id="conversationDiv">
<label>输入你的名字</label><input type="text" id="name"/>
<button id="sendName" onclick="sendName();">发送</button>
<p id="response"></p>
</div>
</div>
<script type="text/javascript">
var stompClient = null;
function setConnected(connected) {
document.getElementById("connect").disabled = connected;
document.getElementById("disconnect").disabled = !connected;
document.getElementById("conversationDiv").style.visibility = connected ? 'visible' : 'hidden';
$("#response").html();
}
function connect() {
var socket = new SockJS('/endpointSang');//通过先前配置的端点建立连接
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected:' + frame);
//开启监听,监听服务器推送到路径/happy/getNewResponse
stompClient.subscribe('/happy/getNewResponse', function (response) {
alert(JSON.parse(response.body).responseMessage);
});
//开启监听,监听服务器推送到路径/happy/getHappyResponse
stompClient.subscribe('/happy/getHappyResponse', function (response) {
console.log(response.body);
})
});
}
//关闭连接
function disconnect() {
if (stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log('Disconnected');
}
//主动发送信息
function sendName() {
var name = $('#name').val();
console.log('name:' + name);
//发送信息到后台监听/welcome路径的controller
stompClient.send("/welcome", {}, JSON.stringify({'name': name}));
}
function showResponse(message) {
$("#response").html(message);
}
</script>
</body>
</html>

运行结果控制台日志:

注:

广播模式,只要所有程序监听同一个后台广播路径就可以了

点对点通信模式,可以在Js端使用随机数或者根据TokenId开启监听路径,后台根据用户的TokenId派发到不同端点就可以了

SpringBoot WebSocket技术的更多相关文章

  1. 基于Springboot后台,前台 vue.js 跨域 Activiti6 工作流(用到websocket技术) 的项目

    工作流模块----------------------------------------------------------------------------------------------- ...

  2. SpringBoot WebSocket STOMP 广播配置

    目录 1. 前言 2. STOMP协议 3. SpringBoot WebSocket集成 3.1 导入websocket包 3.2 配置WebSocket 3.3 对外暴露接口 4. 前端对接测试 ...

  3. 简易集成websocket技术实现消息推送

    Websocket 简介 首先介绍下WebSocket,它是一种网络通信技术,该技术最大的特点就是,服务器端可以主动往客户端发送消息:当然,客户端也可以主动往服务器发送消息,实现两端的消息通信,属于网 ...

  4. Springboot+Websocket+JWT实现的即时通讯模块

    场景 目前做了一个接口:邀请用户成为某课程的管理员,于是我感觉有能在用户被邀请之后能有个立马通知他本人的机(类似微博.朋友圈被点赞后就有立马能收到通知一样),于是就闲来没事搞了一套. ​ 涉及技术栈 ...

  5. HTML5 WebSocket 技术介绍

    WebSocket是html5规范新引入的功能,用于解决浏览器与后台服务器双向通讯的问题,使用WebSocket技术,后台可以随时向前端推送消息,以保证前后台状态统一,在传统的无状态HTTP协议中,这 ...

  6. WebSocket技术

    webSocket技术 在html5技术革新中,加入了WebSocket技术 1.webSocket实际是TCP连接 webSocket在最初将发送http连接请求到服务器端, 但是在header中加 ...

  7. SpringBoot+WebSocket

    SpringBoot+WebSocket 只需三个步骤 导入依赖 <dependency> <groupId>org.springframework.boot</grou ...

  8. 对WebSocket技术的学习与探索(二)

    近日重新开始学习WebSocket技术,什么是WebSocket,在<对WebSocket技术的学习与探索(一)>文章中已经说明白了,还没理解可以看看这篇文章http://www.ruan ...

  9. springboot+websocket+sockjs进行消息推送【基于STOMP协议】

    springboot+websocket+sockjs进行消息推送[基于STOMP协议] WebSocket是在HTML5基础上单个TCP连接上进行全双工通讯的协议,只要浏览器和服务器进行一次握手,就 ...

随机推荐

  1. OS第六章

    OS第七次实验 多进程 添加一个进程体 添加进程B,首先设置i的初值为0x1000,这样来方便程序运行时的时候能区分.其余地方与A一致. 相关变量和宏 Minix中定义了一个数组,叫做tasktab的 ...

  2. [日常摸鱼]bzoj1036 [ZJOI2008]树的统计Count

    听说后天会考x 省选居然还考模板题的么(好吧好像NOI也有考而且也是树剖-) 题意:一棵树,每个点有权值,三种操作:单点修改.求链上最大值.求链上权值和. 直接上模板. 我可能不会写单点修改的线段树了 ...

  3. ctf/web源码泄露及利用办法

    和上一篇文章差不多,也算是对web源码泄露的一个总结,但是这篇文章更侧重于CTF 参考文章: https://blog.csdn.net/wy_97/article/details/78165051? ...

  4. Erlang那些事儿第2回之我是模块(module),一文件一模块

    前几篇文章会写得比较基础,但是既然要写一系列的文章,还是得从基础开始写.我刚学Erlang碰到最大的问题是,想网上搜索下语法,结果却是寥寥无几,而且介绍得不是很系统,对我了解一些细节是有影响的,正好我 ...

  5. K-NN(最近邻分类算法 python

    # algorithm:K-NN(最近邻分类算法)# author:Kermit.L# time: 2016-8-7 #======================================== ...

  6. ADF 第六篇:Copy Data Activity详解

    在Azure 数据工程中,可以使用Copy Data 活动把数据从on-premises 或云中复制到其他存储中.Copy Data 活动必须在一个IR(Integration Runtime)上运行 ...

  7. 【故障公告】redis内存耗尽造成博客后台无法保存

    非常抱歉,今天上午11:00~11:30左右,由于 redis 服务器内存耗尽造成博客后台故障--保存博文时总是提示"请求太过频繁,请稍后再试",由此给您带来麻烦,请您谅解. 由于 ...

  8. Core3.0返回的数据格式xml或json

    前言 此方法从百度得,原文链接找不到了 步骤 //WebAPI接口返回xml格式,由Accept.application决定 services.AddMvc(opt => { opt.Respe ...

  9. C#中获取DataTable某一列的值转换为集合

    直接使用 //Linqvar l1 = (from d in dt.AsEnumerable() select d.Field<int>("ID")).ToList() ...

  10. Linux(Centos7)安装、使用 Docker

    一.Linux(CentOS7) 上安装 docker 1.docker 是什么? docker 是一种 虚拟化容器技术,一个开源的应用容器引擎. 基于镜像,可以秒级启动各种容器(运行一次镜像就生成一 ...