将Websocket与Spring Framework和Vuejs结合使用

Websocket是客户端和服务器之间的全双工(持久)连接,因此两者可以彼此共享信息,而无需重复建立新的连接。 这消除了从客户端重复轮询以从服务器获取更新的需要。

并非所有浏览器都支持Websocket,因此我们利用SockJS javascript库创建WebSocket连接。 SockJS充当抽象层,它首先检查是否对WebSockets提供本机支持,如果不支持,它将尝试使用浏览器支持的协议模仿WebSocket行为。

Spring使用STOMP协议提供了对Websocket的支持,因此我们将使用STOMP.js (用于STOMP协议的javascript实现)与服务器进行交互。

在这篇文章中,客户端将与服务器建立一个websocket连接,并调用在服务器应用程序中注册的websocket端点以接收一些消息。 除此之外,服务器还会从服务器中触发的后台活动向客户端发送一些实时消息。

首先配置服务器。 首先进入start.spring.io并使用以下设置创建一个新的spring boot项目:

配置Websocket

基本的websocket配置包括:

  • 创建用于发布消息的主题地址( /topic/messages
  • 客户端用于调用服务器( /ws )中的WebSocket端点的URL的可选前缀
  • 定义客户端用于与服务器建立WebSocket连接的URL。 ( /connect
 @Configuration  @EnableWebSocketMessageBroker  public class WebsocketConfiguration implements WebSocketMessageBrokerConfigurer { @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint( "/connect" ).withSockJS(); } @Override public void configureMessageBroker(MessageBrokerRegistry registry) { registry.enableSimpleBroker( "/topic/messages" ); registry.setApplicationDestinationPrefixes( "/ws" ); }  } 

创建Websocket端点

我们将创建一个Spring控制器,它将具有两个WebSocket端点,如下所示。 这些端点之一将创建一个无限运行的任务,向客户端发送消息,而另一个端点将取消正在运行的任务。

 @Controller  public class WebsocketController { @Autowired SimpMessagingTemplate simpMessagingTemplate; String destination = "/topic/messages" ; ExecutorService executorService = Executors.newFixedThreadPool(1); Future<?> submittedTask; @MessageMapping( "/start" ) public void startTask(){ if ( submittedTask != null ){ simpMessagingTemplate.convertAndSend(destination, "Task already started" ); return ; } simpMessagingTemplate.convertAndSend(destination, "Started task" ); submittedTask = executorService.submit(() -> { while ( true ){ simpMessagingTemplate.convertAndSend(destination, LocalDateTime.now().toString() + ": doing some work" ); Thread.sleep(10000); } }); } @MessageMapping( "/stop" ) @SendTo( "/topic/messages" ) public String stopTask(){ if ( submittedTask == null ){ return "Task not running" ; } try { submittedTask.cancel( true ); } catch (Exception ex){ ex.printStackTrace(); return "Error occurred while stopping task due to: " + ex.getMessage(); } return "Stopped task" ; }  } 

我已使用上述两种方法将消息发送到配置中定义的主题URL:

  1. 通过注释为@MessageMapping的方法的返回值
  2. 使用SimpMessagingTemplate

Spring boot配置了一个SimpMessagingTemplate实例,我们可以利用它来向主题发送消息。

就像我们定义REST API端点或查看端点的方式一样,通过传递端点URL来使用@MessageMapping注释websocket端点。

用Javascript创建Websocket客户端

我们将首先创建一个HTML页面,其中包含用于启动连接的按钮,然后调用我们定义的websocket端点,如下所示:

 < div class = "content" id= "websocket" > < div > </ div > < div class = "row" > < div class = "col" > <button class = "btn btn-sm btn-info" @click= "connect" >Create connection</button> <button class = "btn btn-sm btn-success" @click= "startTask" >Start Task</button> <button class = "btn btn-sm btn-danger" @click= "stopTask" >Stop Task</button> <button class = "btn btn-sm btn-primary" @click= "disconnect" >Close connection</button> </ div > </ div > < div > </ div > < div class = "row" > < div class = "col" > <ul class = "list-group" style= "height: 500px; overflow:scroll;" > <li class = "list-group-item d-flex justify-content-between align-items-center" v- for = "(m,idx) in messages" :key= "'m-'+idx" > {{m}} </li> </ul> </ div > </ div >  </ div > 

重要的是要注意上面HTML中链接的sockjs和STOMP js库。

所有工作都在Javascript代码中进行,如下所示:

 var stompClient = null;  $(function(){ new Vue({ el: "#websocket" , data: { messages: [] }, methods: { connect: function(){ var socket = new SockJS( '/connect' ); stompClient = Stomp.over(socket); var that = this ; stompClient.connect({}, function(frame) { that.handleMessageReceipt( "Connected" ); stompClient.subscribe( '/topic/messages' , function(messageOutput) { that.handleMessageReceipt(messageOutput.body); }); }); }, disconnect: function(){ if (stompClient != null) { stompClient.disconnect(); } this .handleMessageReceipt( "Disconnected" ); }, startTask: function(){ if ( stompClient != null ){ stompClient.send( "/ws/start" ); } else { alert( "Please connect first" ); } }, stopTask: function(){ if ( stompClient != null ){ stompClient.send( "/ws/stop" ); } else { alert( "Please connect first" ); } }, handleMessageReceipt: function (messageOutput) { this .messages.push(messageOutput); } } });  }); 

connect方法使用/connect端点启动websocket连接。 开始任务方法和停止任务方法调用我们在WebsocketController定义的两个websocket端点

stompClient接收到的消息由`handleMessageReceipt`方法处理。

运行应用程序后,可以创建连接,启动任务,停止任务并获取如下所示的消息:

完整应用程序的代码可以在这里找到。

翻译自: https://www.javacodegeeks.com/2020/02/using-websocket-with-spring-framework-and-vuejs.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/340555.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python函数和模块的使用方法_Python学习06_函数和模块的使用

引入在写有些代码的时候&#xff0c;会发现有些步骤重复了多次&#xff0c;他也不像循环&#xff0c;都是相同的东西在重复&#xff0c;而是指做某件事情的步骤方法&#xff0c;做事的人或对象发生了改变&#xff0c;但是方法却没有改变。要想写出高质量的代码&#xff0c;首先…

tmemo 选择消除行_Divi模块,行和部分加入高级动画选项

一切元素的动画选项每个Divi模块&#xff0c;行和部分都带有高级动画选项&#xff0c;你可以使用这些选项来吸引访问者并使页面更加耀眼。Divi引入一个全新的动画系统&#xff0c;并将这些高级动画选项扩展到每个Divi模块&#xff0c;行和部分&#xff01;这些新选项已合并到一…

java8 streams_Java 8 Friday:使用Streams API时的10个细微错误

java8 streams在Data Geekery &#xff0c;我们喜欢Java。 而且&#xff0c;由于我们真的很喜欢jOOQ的流畅的API和查询DSL &#xff0c;我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 Java 8星期五 每个星期五&#xff0c;我们都会向您展示一些不错的教程风格的Java …

python带参数装饰器 函数名_python 全栈开发,Day11(函数名应用,闭包,装饰器初识,带参数以及带返回值的装饰器)...

一、函数名应用函数名是什么&#xff1f;函数名是函数的名字&#xff0c;本质&#xff1a;变量&#xff0c;特殊的变量。函数名()&#xff0c;执行此函数。python 规范写法1. #后面加一个空格&#xff0c;再写内容&#xff0c;就没有波浪线了。2.一行代码写完&#xff0c;下面一…

python逐行写入excel_快来看看Python如何玩转Excel

来源&#xff1a;ID(innerV)如何用Python来操作Excel文件呢&#xff1f;首先&#xff0c;使用pip 包管理器来安装两个包&#xff0c;安装命令&#xff1a;pip install xlrd pip install xlwt我们来看读取excel的例子&#xff0c;第1行&#xff0c;import 导入xlrd包第4行&#…

python中函数参数_Python函数的参数

本章将介绍函数中参数的用法&#xff0c;更多内容请参考:Python学习指南定义函数的时候&#xff0c;我们把参数的名字和位置确定下来&#xff0c;函数的接口定义就完成了。对于函数的调用者来说&#xff0c;只需要知道传递正确的参数&#xff0c;以及函数就返回什么样的值就够了…

Java面试准备:15个Java面试问题

并非所有的访谈都将重点放在算法和数据结构上—通常&#xff0c;访谈通常只侧重于您声称是专家的语言或技术。在此类访谈中&#xff0c;通常没有任何“陷阱”问题&#xff0c;而是它们要求您利用内存和使用该语言的经验–换句话说&#xff0c;它们测试您对编程语言的了解。 但…

python中字符编码使用_python中字符编码是什么?如何转换字符?

屏幕前我们看到的文字&#xff0c;在计算机中也是这样表示吗&#xff1f;事实上&#xff0c;我们所有的信息电脑是无法直接理解的&#xff0c;同样我们所要表达的信息&#xff0c;计算机也不能看懂。这就需要架起一个理解的桥梁&#xff0c;也就是编码帮助我们相互之间进行翻译…

mysql grant proxy on_MySQL 5.7权限的介绍

MySQL支持的权限如下&#xff1a;ALL或ALL PRIVILEGES 代表指定权限等级的所有权限。ALTER 允许使用ALTER TABLE来改变表的结构&#xff0c;ALTER TABLE同时也需要CREATE和INSERT权限。重命名一个表需要对旧表具有ALTER和DROP权限&#xff0c;对新版具有CREATE和INSERT权限。AL…

python 3.9 发布计划_Python 3.9.0 beta4 发布

Python 3.9.0b4 发布了&#xff0c;Python 3.9 目前仍在开发中&#xff0c;此版本 3.9.0b4 是五个计划的 beta 版本预览中的第四个。Beta 版本预览旨在为广大社区提供测试新功能和错误修复以及准备其项目以支持新功能版本的机会。 Python 3.9 部分主要新功能和变更&#xff1a;…

java junit 异常_JUnit:使用Java 8和Lambda表达式测试异常

java junit 异常在JUnit中&#xff0c;有许多方法可以在测试代码中测试异常&#xff0c;包括try-catch idiom JUnit Rule和catch-exception库。 从Java 8开始&#xff0c;我们还有另一种处理异常的方法&#xff1a;使用lambda表达式。 在这篇简短的博客文章中&#xff0c;我将演…

mysql排插问题_MySQL一次数据插入故障记录

某天突然收到报警&#xff0c;数据库大量事务等待&#xff0c;进到数据库后发线大量的插入操作被阻塞&#xff0c;且都是同一个表的。通过 show engine innodb status 发现插入操作都是在等待索引 idx_create_time(create_time) 的 insert intention lock(跟 gap 锁互斥)&#…

python getopt.getopt_python 参数格式化getopt

命令行参数格式化需要python getopt模块&#xff1a;1.python 命令行参数格式化写道try:options,args getopt.getopt(sys.argv[1:],"hp:i:",["help","ip","port"])except getopt.GetoptError:sys.exit()for name,value in options:i…

使用Zuul和Spring Boot创建API网关

介绍 使用微服务时&#xff0c;通常具有对系统的统一访问点&#xff08;也称为API Gateway &#xff09;。 消费者仅与API网关交谈&#xff0c;而不与服务直接交谈。 这掩盖了您的系统由多个较小的服务组成的事实。 API网关还可帮助解决常见的挑战&#xff0c;例如身份验证&…

纯净pe工具_微PE工具箱2.0

(特殊时期&#xff0c;在家时间多一些&#xff0c;突然想到多年的公众号&#xff0c;重启试试&#xff0c;嗯就先每一天推荐一个软件吧)微PE工具箱(WinPE)是一款非常好用的PE系统(独立的预安装环境)&#xff0c;非常纯净&#xff0c;是装机维护得力的助手。安装简单&#xff0c…

sping jdbc 链接mysql_Spring Boot JDBC 连接数据库示例

文本将对在spring Boot构建的Web应用中&#xff0c;基于MySQL数据库的几种数据库连接方式进行介绍。包括JDBC、JPA、MyBatis、多数据源和事务。JDBC 连接数据库1、属性配置文件(application.properties)spring.datasource.urljdbc:mysql://localhost:3306/testspring.datasourc…

二分查找递归与非递归的时间比较_我们说一说Python的查找算法!

相信大家在面试开发岗和算法岗时&#xff0c;评委最喜欢问的就是&#xff1a;您能给我说一下查找和排序算法有哪些&#xff1f;今天咱们就说一说Python中最常用的查找算法&#xff0c;下期我们再推出排序算法。首先要明白查找是查什么&#xff1f;我们希望能给定一个值&#xf…

ambari mysql error code: 1665_ambari安装中常见的问题

1.openssl版本问题错误如下&#xff1a;ERROR 2018-09-11 14:51:40,101 NetUtil.py:96 - EOF occurred in violation of protocol (_ssl.c:579)ERROR 2018-09-11 14:51:40,101 NetUtil.py:97 - SSLError: Failed to connect. Please check openssl library versions.解决方法&a…

jsf 自定义属性_如何在JSF中实现自定义密码强度指示器

jsf 自定义属性使用JavaScript验证密码强度是一项常见任务。 在本文中&#xff0c;我将展示如何向基于JSF的Web应用程序添加密码强度指示器。 的 PrimeFaces中的密码组件已经具有密码强度的反馈指示符&#xff0c;但是它有两个主要缺点&#xff1a; 反馈指示器没有响应&#…

python编写代码时零_python – KeyError:运行打包代码时为0L

我有一个名为rra.py的脚本,它具有以下skelton结构&#xff1a;usn""usnl[]from bs4 import BeautifulSoupimport reimport asysimport globimport osimport sysimport sysdef inputIndex():#some processsingdef getval():#some processingdef parsehtml():#some pro…