WebSocket 实现前后端通信的笔记
之前在做站内信时,用到了 WebSocket ,整理了一些笔记分享如下。
本文基于 SpringBoot 2.1.5,本文不涉及环境搭建。
引入依赖
在 Spring 中要使用 WebSocket 功能,需要在pom中引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
配置类
增加一个配置类,用于定义 WebSocket 全局配置信息
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer {
/**
* 注册stomp端点
* @param registry
*/
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
## 允许使用socketJs方式访问 即可通过http://IP:PORT/xboot/ws来和服务端websocket连接
registry.addEndpoint("/tmax/ws").setAllowedOrigins("*").withSockJS();
}
/**
* 配置信息代理
* @param registry
*/
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
## 订阅Broker名称 user点对点 topic广播即群发
registry.enableSimpleBroker("/user","/topic");
## 全局(客户端)使用的消息前缀
registry.setApplicationDestinationPrefixes("/app");
## 点对点使用的前缀 无需配置 默认/user
registry.setUserDestinationPrefix("/user");
}
}
来看一下这两个方法:
1、registerStompEndpoints(StompEndpointRegistry registry)
注册stomp端点。起到的作用就是添加一个服务端点,来接收客户端的连接,
registry.addEndpoint("/tmax/ws") 表示添加了一个 /tmax/ws 端点,客户端可以通过这个端点来进行连接。withSockJS() 的作用是开启 SockJS 访问支持,即可通过http://IP:PORT/tmax/ws 来和服务端 websocket 连接。
2、configureMessageBroker(MessageBrokerRegistry registry)
配置信息代理。定义消息代理,设置消息连接请求的各种规范信息。
registry.enableSimpleBroker("/user","/topic") 表示客户端订阅地址的前缀信息,也就是客户端接收服务端消息的地址的前缀信息(比较绕,看完整个例子,大概就能明白了)registry.setApplicationDestinationPrefixes("/app") 指服务端接收地址的前缀,意思就是说客户端给服务端发消息的地址的前缀。
registry.setUserDestinationPrefix("/user") 指推送用户前缀。
我不不难发现,setApplicationDestinationPrefixes 与 setUserDestinationPrefix 起到的效果敲好相反,一个定义了客户端接收的地址前缀,一个定义了客户端发送地址的前缀。
开始业务代码的编写
先了解几个知识点,下方会用到。
1、MessageMapping
接收客户端请求连接注解。Spring 对于 WebSocket 封装的特别简单,提供了一个 @MessageMapping 注解,功能类似 @RequestMapping,它是存在于Controller中的,定义一个消息的基本请求,功能也跟 @RequestMapping类似,包括支持通配符 的url定义等等。
2、SimpMessagingTemplate
SimpMessagingTemplate 是 Spring-WebSocket 内置的一个消息发送工具,可以将消息发送到指定的客户端。
3、SendTo
@SendTo 可以把消息广播到路径上去,例如下面可以把消息广播到 "/topic/greetings”,如果客户端在这个路径订阅消息,则可以接收到消息
接下来看一下后台代码实现,HelloController
/**
* @author niceyoo
*/
@Slf4j
@Controller
@Api(description = "hello接口")
@Transactional
public class HelloController {
@Autowired
private SimpMessagingTemplate messagingTemplate;
/**
* 跳转至hello.html界面
* @return
*/
@RequestMapping("/hello")
public String hello(){
return "hello";
}
/**
* 接收然后转发至客户端消息
* @param message
* @return
* @throws Exception
*/
@MessageMapping("/top")
@SendTo("/topic/greetings")
public String greeting(String message) throws Exception {
System.out.println("receiving " + message);
System.out.println("connecting successfully.");
return "AAA:"+message;
}
/**
* 推送消息
* @return
*/
@ResponseBody
@RequestMapping("/hello/addMessage")
public Result<Object> addMessage(){
messagingTemplate.convertAndSend("/topic/greetings", "您收到了新的系统消息");
return new ResultUtil<Object>().setSuccessMsg("添加成功");
}
}
hello.html 代码:
<!doctype html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/sockjs-client/1.3.0/sockjs.js"></script>
<script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.js"></script>
<style>
.box {
width: 300px;
float: left;
margin: 0 20px 0 20px;
}
.box div, .box input {
border: 1px solid;
-moz-border-radius: 4px;
border-radius: 4px;
width: 100%;
padding: 0px;
margin: 5px;
}
.box div {
border-color: grey;
height: 300px;
overflow: auto;
}
.box input {
height: 30px;
}
h1 {
margin-left: 30px;
}
body {
background-color: #F0F0F0;
font-family: "Arial";
}
</style>
</head>
<body lang="en">
<h1>Index</h1>
<div id="first" class="box">
<div></div>
<input autocomplete="off" value="Type here..."></input>
<button onclick="connect()">登陆客户端</button>
<button onclick="send()">发送消息</button>
</div>
<script>
var stompClient = null;
var sockjs_url = '/tmax/ws';
function connect() {
var sockjs = new SockJS(sockjs_url);
stompClient = Stomp.over(sockjs);
stompClient.connect({}, function(frame) {
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function(greeting){
console.log("返回内容:"+greeting.body);
print('服务器:', greeting.body);
});
});
}
function send() {
if(stompClient == null){
print('系统提示:', '请先点击客户端登陆');
return false;
}
print('客户端:', inp.val());
stompClient.send("/app/top", {}, inp.val());
inp.val('');
}
$('#first input').focus();
var div = $('#first div');
var inp = $('#first input');
var print = function(m, p) {
p = (p === undefined) ? '' : p;
div.append($("<code>").text(m + ' ' + p));
div.append($("<br>"));
div.scrollTop(div.scrollTop()+10000);
};
</script>
</body>
</html>
操作流程:

点击“登录客户端”,输入框内输入内容,点击发送消息。
消息推送
关于消息的推送,借助 postman,调用 http://127.0.0.1:8888/hello/addMessage,实现后端推送至客户端。

额外补充,关于消息推送,往往会用到推送至指定用户,则:messagingTemplate.convertAndSendToUser(id,"/queue/subscribe", "您收到了新的消息"); ,其中id为系统用户id。
详细可搜索 SimpMessagingTemplate 的一些用法。
如果文章有错的地方欢迎指正,大家互相留言交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:niceyoo

参考地址:https://www.jianshu.com/p/60799f1356c5
WebSocket 实现前后端通信的笔记的更多相关文章
- 如何使用websocket实现前后端通信
websocket通信是很好玩的,也很有用的的通信方式,使用方式如下: 第一步由于springboot很好地集成了websocket,所以先在在pom.xml文件中引入依赖 <dependenc ...
- WebSocket实现前后端通讯
WebSocket实现前后端通讯 长安如梦里,何日是归期. 简介:我们上线了一个商城项目,移交运营团队使用之后,他们要求商城有新订单来的时候同时加上声音提示,让她们可以及时知道有单来了.我这边想了想, ...
- web——前后端通信原理
前端向后台传输数据: 传输方法:post get 区别: (1)get:用于从服务器获取数据,将参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看 ...
- web——前后端通信
前端向后台传输数据: 传输方法:post get 区别: (1)get:用于从服务器获取数据,将参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看 ...
- 前后端通信—webSocket(支持跨域)
WebSocket 的介绍 WebSocket 是什么 WebSocket 是一种网络通信协议.RFC6455 定义了它的通信标准. WebSocket 是 HTML5 开始提供的一种在单个 TCP ...
- C++ protobuffer 前后端通信 简单应用
后端发送多个protobuffer消息到前端,前端用socket监听,如何区分消息类型呢? //定义心跳包 DseHeartbeat _DseHeartbeat; DseHeartbeat _DseH ...
- H5页面前后端通信 (3种方式简单介绍)
1.ajax:短连接 2.websocket :长连接,双向的. node搭建的websocket服务器,推送信息给客户端浏览器 :https://www.cnblogs.com/fps2tao/ ...
- SpringBoot整合WebSocket实现前后端互推消息
小编写这篇文章是为了记录实现WebSocket的过程,受不了啰嗦的同学可以直接看代码. 前段时间做项目时设计了一个广播的场景,具体业务不再赘述,最终要实现的效果就是平台接收到的信息实时发布给所有的用户 ...
- Web端在线实时聊天,基于WebSocket(前后端分离)
这是一个简易的Demo,已经实现了基础的功能 之前一直想实现一个实时聊天的系统,一直没有去实践他.有一天吃饭的时候扫码点菜,几个人点菜能够实时更新,当时就在想,这应该是同一种技术. 刚好前段时间项目上 ...
随机推荐
- Django-05-视图函数
http请求中产生两个核心对象: http请求:HttpRequest对象 http响应:HttpResponse对象 所在位置:django.http 之前我们用到的参数request就是HttpR ...
- 创建包含CRUD操作的Web API接口4:实现Put方法
本节教程是前三节的延续,在前面我们创建了Web API和必要的基础设施,也实现了Get和Post方法.接下来,我们将在Web API中实现Put方法. RESTful架构中,HTTP PUT方法用于在 ...
- ArcGIS加载数据中常用的File文件方法总结
在介绍ArcGIS中各种数据的打开方法时,我们用到了许多对于File文件的操作,在此做一个常用用法的总结.例如, 介绍ArcGIS中各种数据的打开方法——mxd(地图文档) 以方法一为例:运用Load ...
- C#泛型集合之——列表
列表基础 1.列表概述:列表与哈希集合不同之处在于,它的元素可以重复.(更接近逻辑上的数组,而哈希集合更接近于数学上的集合) 2.创建及初始化: (1)List<类型> 列表名 =new ...
- [golang]按图片中心旋转后的新图左顶点和原图左顶点的偏移量计算
1 前言 略,作为记录使用 2 代码 /** * @Author: FB * @Description: * @File: RotateSample.go * @Version: 1.0.0 * @D ...
- How do you run an interactive process in Dart?
https://stackoverflow.com/questions/12682269/how-do-you-run-an-interactive-process-in-dart The test ...
- Windows查看端口使用状况(转)
转:https://www.cnblogs.com/lixuwu/p/5898354.html 阅读目录 1 查看windows所有端口进程 2 查询指定端口 使用端口是我们在进行远程或者打印机等都会 ...
- 【转载】C#中List集合使用Max()方法查找到最大值
在C#的List集合操作中,有时候需要查找到List集合中的最大值,此时可以使用List集合的扩展方法Max方法,Max方法有2种形式,一种是不带任何参数的形式,适用于一些值类型变量的List集合,另 ...
- LocalStorageUtils
对localStorage进行封装: var LocalStorageUtils = new function (){ if(window.localStorage==null){ throw new ...
- tf常见的损失函数(LOSS)汇总
损失函数在机器学习中用于表示预测值与真实值之间的差距.一般而言,大多数机器学习模型都会通过一定的优化器来减小损失函数从而达到优化预测机器学习模型参数的目的. 哦豁,损失函数这么必要,那都存在什么损失函 ...