栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

详解springboot集成websocket的两种实现方式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

详解springboot集成websocket的两种实现方式

WebSocket跟常规的http协议的区别和优缺点这里大概描述一下

一、websocket与http 

http协议是用在应用层的协议,他是基于tcp协议的,http协议建立链接也必须要有三次握手才能发送信息。http链接分为短链接,长链接,短链接是每次请求都要三次握手才能发送自己的信息。即每一个request对应一个response。长链接是在一定的期限内保持链接。保持TCP连接不断开。客户端与服务器通信,必须要有客户端发起然后服务器返回结果。客户端是主动的,服务器是被动的。 
WebSocket是HTML5中的协议, 他是为了解决客户端发起多个http请求到服务器资源浏览器必须要经过长时间的轮训问题而生的,他实现了多路复用,他是全双工通信。在webSocket协议下客服端和浏览器可以同时发送信息。

二、HTTP的长连接与websocket的持久连接

HTTP1.1的连接默认使用长连接(persistent connection),

即在一定的期限内保持链接,客户端会需要在短时间内向服务端请求大量的资源,保持TCP连接不断开。客户端与服务器通信,必须要有客户端发起然后服务器返回结果。客户端是主动的,服务器是被动的。

  在一个TCP连接上可以传输多个Request/Response消息对,所以本质上还是Request/Response消息对,仍然会造成资源的浪费、实时性不强等问题。

如果不是持续连接,即短连接,那么每个资源都要建立一个新的连接,HTTP底层使用的是TCP,那么每次都要使用三次握手建立TCP连接,即每一个request对应一个response,将造成极大的资源浪费。

  长轮询,即客户端发送一个超时时间很长的Request,服务器hold住这个连接,在有新数据到达时返回Response

websocket的持久连接  只需建立一次Request/Response消息对,之后都是TCP连接,避免了需要多次建立Request/Response消息对而产生的冗余头部信息。

Websocket只需要一次HTTP握手,所以说整个通讯过程是建立在一次连接/状态中,而且websocket可以实现服务端主动联系客户端,这是http做不到的。

springboot集成websocket的不同实现方式:

pom添加依赖

 
      org.springframework.boot
      spring-boot-starter-websocket
    

 因涉及到js连接服务端,所以也写了对应的html,这里集成下thymeleaf模板,前后分离的项目这一块全都是前端做的

 
      org.springframework.boot
      spring-boot-starter-thymeleaf
    

配置文件:

server:
 port: 8885
 
#添加Thymeleaf配置
thymeleaf:
 cache: false
 prefix: classpath:/templates/
 suffix: .html
 mode: HTML5
 encoding: UTF-8
 content-type: text/html

1:自定义WebSocketServer,使用底层的websocket方法,提供对应的onOpen、onClose、onMessage、onError方法

1.1:添加webSocketConfig配置类


@Configuration
public class WebSocketConfig {
  @Bean
  public ServerEndpointExporter serverEndpointExporter() {
    return new ServerEndpointExporter();
  }
}

1.2:添加webSocketServer服务端类

package com.example.admin.web;
 

 
@ServerEndpoint("/websocket/{sid}")
@Component
@Slf4j
public class WebSocketServer {
  //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
  private static int onlineCount = 0;
  //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
  private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet();
 
  //与某个客户端的连接会话,需要通过它来给客户端发送数据
  private Session session;
 
  //接收sid
  private String sid="";
 
 
  */






@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
 
//  这个方法的作用是添加一个服务端点,来接收客户端的连接。
//  registry.addEndpoint("/socket")表示添加了一个/socket端点,客户端就可以通过这个端点来进行连接。
//  withSockJS()的作用是开启SockJS支持,
  @Override
  public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/socket").withSockJS();
  }
  @Override
  public void configureMessageBroker(MessageBrokerRegistry registry) {
    //表示客户端订阅地址的前缀信息,也就是客户端接收服务端消息的地址的前缀信息
    registry.enableSimpleBroker("/topic");
    //指服务端接收地址的前缀,意思就是说客户端给服务端发消息的地址的前缀
    registry.setApplicationDestinationPrefixes("/app");
  }
}

 2.2:controller提供对应请求的接口

//页面请求
  @GetMapping("/socket2")
  public ModelAndView socket2() {//@PathVariable String userId
    ModelAndView mav=new ModelAndView("html/socket2");
    //mav.addObject("userId", userId);
    return mav;
  }
 
  
  @MessageMapping("/change-notice")//客户端访问服务端的时候config中配置的服务端接收前缀也要加上 例:/app/change-notice
  @SendTo("/topic/notice")//config中配置的订阅前缀记得要加上
  public CustomMessage greeting(CustomMessage message){
    System.out.println("服务端接收到消息:"+message.toString());
    //我们使用这个方法进行消息的转发发送!
    //this.simpMessagingTemplate.convertAndSend("/topic/notice", value);(可以使用定时器定时发送消息到客户端)
    //    @Scheduled(fixedDelay = 1000L)
    //    public void time() {
    //      messagingTemplate.convertAndSend("/system/time", new Date().toString());
    //    }
    //也可以使用sendTo发送
    return message;
  }

2.3:提供socket2.html




  
  Spring Boot+WebSocket+广播式
 


2.4:对应的js引用可以去网上下载

2.5:浏览器debug访问localhost:8885/system/socket2,点击连接连接到服务器,数据内容可以推送到服务器以及服务器消息回推。

2.6:实现前端和服务端的轮训可以页面Ajax轮训也可以后端添加定时器

@Component
@EnableScheduling
public class Timetask {
  private static Logger logger = LoggerFactory.getLogger(Timetask.class);
 
  @Scheduled(cron = "0/20 * * * * ?")
  public void test(){
    System.err.println("*********  定时任务执行  **************");
    CopyOnWriteArraySet webSocketSet =
 WebSocketServer.getWebSocketSet();
    int i = 0 ;
    webSocketSet.forEach(c->{
      try {
 c.sendMessage(" 定时发送 " + new Date().toLocaleString());
      } catch (IOException e) {
 e.printStackTrace();
      }
    });
 
    System.err.println("/n 定时任务完成.......");
  }
}

代码在https://github.com/huiyunfei/spring-cloud.git 的admin项目里

基于STOMP协议的广播模式和点对点模式消息推送可参考:

https://www.cnblogs.com/hhhshct/p/8849449.html

https://www.cnblogs.com/jmcui/p/8999998.html

到此这篇关于springboot集成websocket的两种实现方式的文章就介绍到这了,更多相关springboot集成websocket内容请搜索考高分网以前的文章或继续浏览下面的相关文章希望大家以后多多支持考高分网!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/129262.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号