Spring4.0系列9-websocket简单应用

简介:

spring 4.0的一个最大更新是增加了websocket的支持。websocket提供了一个在web应用中的高效、双向的通讯,需要考虑到客户端(浏览器)和服务器之间的高频和低延时消息交换。一般的应用场景有:在线交易、游戏、协作、数据可视化等。

 

使用websocket需要考虑的浏览器的支持(IE<10不支持),目前主流的浏览器都能很好的支持websocket。

websocket协议中有一些子协议,可以从更高的层次实现编程模型,就像我们使用HTTP而不是TCP一样。这些子协议有STOMP,WAMP等。

 

本教程只考虑websocket的简单实用,包含Spring对JSR-356的支持及Spring WebSocket API。

1、Java API for WebSocket(JSR-356)

Java API for WebSocket已经是Java EE 7的一部分。它定义了两类endpoit(都是EndPoint类的子类),使用注解标识@ClientEndpoint和@ServerEndpoint。

 

1.1 Servlet容器扫描初始化

通过Spring初始化一个endpoint,只需配置一个SpringConfigurator在类上的@ServerEndpoint注解上。

 

Java代码   收藏代码
  1. import javax.websocket.server.ServerEndpoint;  
  2. import org.springframework.web.socket.server.endpoint.SpringConfigurator;  
  3.   
  4.   
  5. @ServerEndpoint(value = "/echo", configurator = SpringConfigurator.class);  
  6. public class EchoEndpoint {  
  7.   
  8.   private final EchoService echoService;  
  9.   
  10.   @Autowired  
  11.   public EchoEndpoint(EchoService echoService) {  
  12.     this.echoService = echoService;  
  13.   }  
  14.   
  15.   @OnMessage  
  16.   public void handleMessage(Session session, String message) {  
  17.     // ...  
  18.   }  
  19.   
  20. }  

 上例假设SpringContextLoaderListener用来加载配置,这是个典型的web应用。Servlet容器将通过扫描@ServerEndpoint和SpringConfigurator初始化一个新的websocket会话。

 1.2 Spring 初始化

如果你想使用一个单独的实例而不使用Servlet容器扫描,将EchoEndpoint类声明称一个bean,并增加一个ServerEndpointExporter的bean:

Java代码   收藏代码
  1. import org.springframework.web.socket.server.endpoint.ServerEndpointExporter;  
  2.   
  3.   
  4. @Configuration  
  5. public class EndpointConfig {  
  6.   
  7.   @Bean  
  8.   public EchoEndpoint echoEndpoint() {  
  9.     return new EchoEndpoint(echoService());  
  10.   }  
  11.   
  12.   @Bean  
  13.   public EchoService echoService() {  
  14.     // ...  
  15.   }  
  16.   
  17.   @Bean  
  18.   public ServerEndpointExporter endpointExporter() {  
  19.     return new ServerEndpointExporter();  
  20.   }  
  21.   
  22. }  

 

 EchoEndpoint 可以通过EndPointRegistration发布:

Java代码   收藏代码
  1. import org.springframework.web.socket.server.endpoint.ServerEndpointExporter;  
  2. import org.springframework.web.socket.server.endpoint.ServerEndpointRegistration;  
  3.   
  4.   
  5. @Configuration  
  6. public class EndpointConfig {  
  7.   
  8.   @Bean  
  9.   public EndpointRegistration echoEndpoint() {  
  10.     return new EndpointRegistration("/echo", EchoEndpoint.class);  
  11.   }  
  12.   
  13.   @Bean  
  14.   public ServerEndpointExporter endpointExporter() {  
  15.     return new ServerEndpointExporter();  
  16.   }  
  17.   
  18.   // ..  
  19.   
  20. }  

 本例源码:spring-websocket-test-endpoint.zip

2、Spring WebSocket API

Spring WebSocket API提供了SockJS的支持,且有些容器如Jetty 9目前还没有对JSR-356的支持,所以有Spring WebSocket API是必要的。

 

Spring WebSocket API的核心接口是WebSocketHandler。下面是一个处理文本消息的handler的实现:

Java代码   收藏代码
  1. import org.springframework.web.socket.adapter.TextWebSocketHandlerAdapter;  
  2.   
  3.   
  4. public class EchoHandler extends TextWebSocketHandlerAdapter {  
  5.   
  6.   @Override  
  7.   public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {  
  8.     session.sendMessage(message);  
  9.   }  
  10.   
  11. }  

 

WebSocketHandler可以通过WebSocketHttpRequestHandler插入到Spring MVC里:

Java代码   收藏代码
  1. import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler;  
  2.   
  3.   
  4. @Configuration  
  5. public class WebConfig {  
  6.   
  7.   @Bean  
  8.   public SimpleUrlHandlerMapping handlerMapping() {  
  9.   
  10.     Map<String, Object> urlMap = new HashMap<String, Object>();  
  11.     urlMap.put("/echo"new WebSocketHttpRequestHandler(new EchoHandler()));  
  12.   
  13.     SimpleUrlHandlerMapping hm = new SimpleUrlHandlerMapping();  
  14.     hm.setUrlMap(urlMap);  
  15.     return hm;  
  16.   }  
  17.   
  18. }  

 SockJS服务器端的支持

SockJs是一个脚本框架,它提供类似于websocket的编程模式但是可以适应不同的浏览器(包括不支持websocket的浏览器)。

 

开启SockJS的支持,声明一个SockJsService,和一个url映射,然后提供一个WebSocketHandler来处理消息。虽然我们是哟个SockJS我们开发的方式是一样的,但是随着浏览器的不同传输的协议可以是Http Streaming,long polling等。

 

Java代码   收藏代码
  1. import org.springframework.web.socket.sockjs.SockJsService;  
  2. // ...  
  3.   
  4.   
  5. @Configuration  
  6. public class WebConfig {  
  7.   
  8.   @Bean  
  9.   public SimpleUrlHandlerMapping handlerMapping() {  
  10.   
  11.     SockJsService sockJsService = new DefaultSockJsService(taskScheduler());  
  12.   
  13.     Map<String, Object> urlMap = new HashMap<String, Object>();  
  14.     urlMap.put("/echo/**"new SockJsHttpRequestHandler(sockJsService, new EchoHandler()));  
  15.   
  16.     SimpleUrlHandlerMapping hm = new SimpleUrlHandlerMapping();  
  17.     hm.setUrlMap(urlMap);  
  18.     return hm;  
  19.   }  
  20.   
  21.   @Bean  
  22.   public ThreadPoolTaskScheduler taskScheduler() {  
  23.     ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();  
  24.     taskScheduler.setThreadNamePrefix("SockJS-");  
  25.     return taskScheduler;  
  26.   }  
  27.   
  28. }  

 

在我们实际使用中我们会使用WebSocketConfigurer集中注册WebSocket服务:

Java代码   收藏代码
  1. @Configuration  
  2. @EnableWebMvc  
  3. @EnableWebSocket//开启websocket  
  4. public class WebConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer {  
  5.   
  6.     @Override  
  7.     public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {  
  8.   
  9.         registry.addHandler(echoWebSocketHandler(), "/echo"); //提供符合W3C标准的Websocket数据  
  10.         registry.addHandler(snakeWebSocketHandler(), "/snake");  
  11.   
  12.         registry.addHandler(echoWebSocketHandler(), "/sockjs/echo").withSockJS();//提供符合SockJS的数据  
  13.         registry.addHandler(snakeWebSocketHandler(), "/sockjs/snake").withSockJS();  
  14.     }  
  15.   
  16.     @Bean  
  17.     public WebSocketHandler echoWebSocketHandler() {  
  18.         return new EchoWebSocketHandler(echoService());  
  19.     }  
  20.   
  21.     @Bean  
  22.     public WebSocketHandler snakeWebSocketHandler() {  
  23.         return new PerConnectionWebSocketHandler(SnakeWebSocketHandler.class);  
  24.     }  
  25.   
  26.     @Bean  
  27.     public DefaultEchoService echoService() {  
  28.         return new DefaultEchoService("Did you say \"%s\"?");  
  29.     }  
  30.   
  31.     // Allow serving HTML files through the default Servlet  
  32.   
  33.     @Override  
  34.     public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {  
  35.         configurer.enable();  
  36.     }  
  37.   
  38. }  

  

SockJS客户端代码:

Java代码   收藏代码
  1. ws = new SockJS(url, undefined, {protocols_whitelist: transports}) ;   //初始化 websocket  
  2.            
  3. ws.onopen = function () {  
  4.                 setConnected(true);  
  5.                 log('Info: connection opened.');  
  6.             };  
  7.   
  8. ws.onmessage = function (event) {  
  9.                 log('Received: ' + event.data); //处理服务端返回消息  
  10.             };  
  11.   
  12. ws.onclose = function (event) {  
  13.                 setConnected(false);  
  14.                 log('Info: connection closed.');  
  15.                 log(event);  
  16.             };  
  17.   
  18.  ws.send(message);//向服务端发送消息  
目录
相关文章
|
18天前
|
XML Java 数据库
探索 Spring Boot 中的 @Configuration 注解:核心概念与应用
【4月更文挑战第20天】在 Spring Boot 项目中,@Configuration 注解扮演了一个关键角色,它标识一个类作为配置源,这些配置用于定义和管理 Spring 应用程序中的 Bean
63 7
|
16天前
|
存储 设计模式 JavaScript
第六篇 再谈观察者模式的具体应用,如监听一个class其中一个属性,如websocket中onmessage的实现
第六篇 再谈观察者模式的具体应用,如监听一个class其中一个属性,如websocket中onmessage的实现
|
18天前
|
前端开发 Java 测试技术
Java一分钟之Spring MVC:构建Web应用
【5月更文挑战第15天】Spring MVC是Spring框架的Web应用模块,基于MVC模式实现业务、数据和UI解耦。常见问题包括:配置DispatcherServlet、Controller映射错误、视图解析未设置、Model数据传递遗漏、异常处理未配置、依赖注入缺失和忽视单元测试。解决这些问题可提升代码质量和应用性能。注意配置`web.xml`、`@RequestMapping`、`ViewResolver`、`Model`、`@ExceptionHandler`、`@Autowired`,并编写测试用例。
306 3
|
18天前
|
Java 应用服务中间件 测试技术
深入探索Spring Boot Web应用源码及实战应用
【5月更文挑战第11天】本文将详细解析Spring Boot Web应用的源码架构,并通过一个实际案例,展示如何构建一个基于Spring Boot的Web应用。本文旨在帮助读者更好地理解Spring Boot的内部工作机制,以及如何利用这些机制优化自己的Web应用开发。
42 3
|
18天前
|
安全 Java 开发者
深入理解Spring Boot配置绑定及其实战应用
【4月更文挑战第10天】本文详细探讨了Spring Boot中配置绑定的核心概念,并结合实战示例,展示了如何在项目中有效地使用这些技术来管理和绑定配置属性。
23 1
|
18天前
|
网络协议 Java Go
【Go语言专栏】Go语言中的WebSocket实时通信应用
【4月更文挑战第30天】Go语言(Golang)是Google开发的编程语言,适用于云计算、微服务等领域。本文介绍了WebSocket,一种实现浏览器与服务器全双工通信的协议,其特点是实时性、全双工和轻量级。在Go中实现WebSocket,可以使用gorilla/websocket库。示例展示了如何创建服务器端和客户端,实现消息的收发。WebSocket广泛应用于聊天、游戏、通知推送和实时数据同步等场景。学习Go语言中的WebSocket对于开发实时通信应用至关重要。
|
5天前
|
前端开发 IDE Java
构建一个基于React和Spring Boot的简易聊天室应用
构建一个基于React和Spring Boot的简易聊天室应用
21 0
|
10天前
|
Java 关系型数据库 Docker
docker打包部署spring boot应用(mysql+jar+Nginx)
docker打包部署spring boot应用(mysql+jar+Nginx)
|
11天前
|
Java Maven Docker
Docker化Spring Boot3应用:从镜像构建到部署
本文介绍了如何在Linux上通过命令行构建和运行Spring Boot 3服务的Docker镜像。首先,基于Ubuntu创建包含JDK 21的基础镜像,然后使用Maven打包Spring Boot应用。接着,构建服务镜像,将应用和依赖添加到镜像中,并设置工作目录和暴露端口。最后,利用docker-compose部署服务,挂载宿主机目录以方便更新静态文件。Docker简化了应用部署,确保了不同环境的一致性。
63 2
Docker化Spring Boot3应用:从镜像构建到部署
|
12天前
|
Cloud Native Java 关系型数据库
【阿里云云原生专栏】构建云原生应用:基于Spring Boot与阿里云服务的全栈指南
【5月更文挑战第21天】构建云原生应用是企业数字化转型的关键,本文提供了一份基于Spring Boot和阿里云的全栈指南。涵盖从阿里云账号注册、ECS与Docker搭建,到Spring Boot项目创建、业务代码编写和部署。此外,还介绍了如何集成阿里云OSS存储、RDS数据库服务以及ACK容器服务,助力打造高效、可扩展和易管理的云原生应用。
137 3