又是一个老套的古诗词赏析
不恨此花飞尽,恨西园、落红难缀。——苏轼《水龙吟·次韵章质夫杨花词》
WebSocket与STOMP协议
相关简介
WebSocket
WebSocket 是一种网络通信协议,很多高级功能都需要它。够精辟吧
初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?
答案很简单,因为 HTTP 协议有一个缺陷:通信只能由客户端发起。
举例来说,我们想了解今天的天气,只能是客户端向服务器发出请求,服务器返回查询结果。HTTP 协议做不到服务器主动向客户端推送信息。
这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。最典型的场景就是聊天室。
轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。
STOMP
STOMP是一个更高级的协议,它使用一个基于帧(frame)的格式来定义消息,与HTTP的request和response类似。
STOMP即Simple (or Streaming) Text Orientated Messaging Protocol,简单(流)文本定向消息协议,它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消息代理(Broker)进行交互。STOMP协议由于设计简单,易于开发客户端,因此在多种语言和多种平台上得到广泛地应用。
STOMP协议的前身是TTMP协议(一个简单的基于文本的协议),专为消息中间件设计。
STOMP是一个非常简单和容易实现的协议,其设计灵感源自于HTTP的简单性。尽管STOMP协议在服务器端的实现可能有一定的难度,但客户端的实现却很容易。例如,可以使用Telnet登录到任何的STOMP代理,并与STOMP代理进行交互。
别问,问就是百度抄来的
示例使用框架
SpringBoot+JS 觉得low的大佬左上角可以点X了
开始实践
很多解释都在代码的注释中,细细品味
01
导入依赖
<dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-websocketartifactId> dependency> <dependency> <groupId>org.webjarsgroupId> <artifactId>sockjs-clientartifactId> <version>1.1.2version> dependency> <dependency> <groupId>org.webjarsgroupId> <artifactId>jqueryartifactId> <version>3.5.1version> dependency> <dependency> <groupId>org.webjarsgroupId> <artifactId>stomp-websocketartifactId> <version>2.3.3-1version> dependency> <dependency> <groupId>org.webjarsgroupId> <artifactId>webjars-locatorartifactId> <version>0.40version> dependency>
导入前端相关的jar依赖是为了减少收集js文件,页面中直接获取即可
02
编写配置类
package com.websit.formerly.sdk.websocket;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;/** * @program: formerly * @description: websocket配置类 * @author: ShiDunKai * @create: 2020-10-13 15:13 **//** * 配置WebSocket,需要在配置类上使用@EnableWebSocketMessageBroker开启WebSocket支持 * @EnableWebSocketMessageBroker注解同时会开启使用STOMP协议来传输基于代理(message broker)用的消息, * 这时控制器支持使用@MessageMapping,就像使用@RequestMapping一样。 */@Configuration@EnableWebSocketMessageBrokerpublic class WebSocketConfig implements WebSocketMessageBrokerConfigurer { /** * 配置消息代理类 */ @Override public void configureMessageBroker(MessageBrokerRegistry registry) { //设置消息代理前缀 registry.enableSimpleBroker("/topic"); //设置app代理前缀 registry.setApplicationDestinationPrefixes("/app"); } /** * 注册STOMP协议的节点(endpoint)并映射指定的URL */ @Override public void registerStompEndpoints(StompEndpointRegistry registry) { //设置连接点 registry.addEndpoint("/wechat").withSockJS(); }}
注意连接点与代理、消息前缀的名称
03
编写controller
package com.websit.formerly.sdk.websocket;import org.springframework.messaging.handler.annotation.MessageMapping;import org.springframework.messaging.handler.annotation.SendTo;import org.springframework.stereotype.Controller;/** * @program: formerly * @description: websocketcontroller * @author: ShiDunKai * @create: 2020-10-13 15:25 **/@Controllerpublic class WebSocketController { /** * 当浏览器向服务端发送请求时,通过@MessageMapping映射/welcome这个地址,类似于@RequestMapping * 当服务端有消息时,会对订阅了@SendTo中的路径的浏览器发送消息 */ @MessageMapping("/hello") @SendTo("/topic/getting") public MessageBean getting(MessageBean messageBean){ return messageBean; }}
04
编写页面
<html lang="en"><head> <meta charset="UTF-8"> <title>sdk聊天室title>head><body><table> <tr> <td> 请输入用户名: td> <td> <input type="text" id="name"/> td> tr> <tr> <td> <input type="button" id="connect" value="连接"> td> <td> <input type="button" disabled="disabled" id="disconnect" value="断开连接"> td> tr>table><div id="chat" style="display: none"> <table> <tr> <td>请输入聊天内容td> <td><input type="text" id="content">td> <td><input type="button" id="send" value="发送">td> <td>td> tr> table> <div id="conversation"> 群聊进行中...... div>div>body><script src="/webjars/sockjs-client/sockjs.min.js">script><script src="/webjars/stomp-websocket/stomp.min.js">script><script src="/webjars/jquery/jquery.min.js">script><script> $(function (){ $("#connect").click(function(){ connect(); }) $("#disconnect").click(function () { if (stompClient!=null){ stompClient.disconnect(); } setConnected(false); }) $("#send").click(function () { stompClient.send('/app/hello',{},JSON.stringify({'name':$('#name').val(),'commont':$('#content').val()})) }) }) var stompClient=null; function connect(){ if (!$("#name").val()){ return; } var socket=new SockJS('/wechat'); stompClient=Stomp.over(socket); //建立连接 stompClient.connect({},function (success) { //连接成功 setConnected(true); stompClient.subscribe('/topic/getting',function (msg) { showGetting(JSON.parse(msg.body)); }) }) } function showGetting(msg) { $("#conversation").append('
'+msg.name+':'+msg.commont+'
'); } //处理页面显示 function setConnected(flag){ $("#connect").prop("disabled",flag); $("#disconnect").prop("disabled",!flag); if (flag){ $("#chat").show(); }else{ $("#chat").hide(); } }script>html>
效果如下
张三连接,李四连接
张三发送消息,李四收到
李四发送消息,张三收到
这样的话聊天室的最基本的功能就实现了,如何实现点对点的聊天?更漂亮的页面,更全的个人信息,拉黑......等,来日方长
又水了一篇文章,我就来试试公众号文章的样式好不好用,好不好看,目前还是比较满意的,就是太麻烦了,下次整个通篇都是粉色的试试
晚安。
参考:江南一点雨 百度 喜欢就点个在看再走吧