spring对websocket的集成和使用

WebSocket是HTML5提出的一个用于通信的协议规范,该协议通过一个握手机制,在客户端和服务端之间建立一个类似于TCP的连接,从而方便客户端和服务端之间的通信。

WebSocket协议本质上是一个基于TCP的协议,是先通过HTTP/HTTPS协议发起一条特殊的HTTP请求进行握手后创建一个用于交换数据的TCP连接,此后服务端与客户端通过此TCP连接进行实时通信。客户端和服务端只需要要做一个握手的动作,在建立连接之后,服务端和客户端之间就可以通过此TCP连接进行实时通信。

websocket是建立在物理层上的连接,相比于基于网络层的长连接可以节约资源,相比于AJAX轮训可以降低服务器压力。

spring在4.0后将websocket集成进去,要使用spring的websocket的话,spring的版本要在4.0及以上。

spring使用websocket需要的jar(pom.xml)

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-websocket</artifactId>
    <version>4.0.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-messaging</artifactId>
    <version>4.0.6.RELEASE</version>
</dependency>

web.xml中对websocket的配置

  <servlet>
      <servlet-name>springMVC</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:/springMVC/spring-webSocket.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
      <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
      <servlet-name>springMVC</servlet-name>
      <url-pattern>/</url-pattern>
    </servlet-mapping> 

springMVC中对websocket的配置

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/websocket
            http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd">

    <!-- websocket处理类 -->
    <bean id="msgHandler" class="com.test.websocket.MsgWebSocketHandler" />
    <!-- 握手接口/拦截器 ,看项目需求是否需要-->
    <bean id="handshakeInterceptor" class="com.test.websocket.HandshakeInterceptor" />
    <websocket:handlers>
        <websocket:mapping path="/websocket" handler="msgHandler" />
        <websocket:handshake-interceptors>
            <ref bean="handshakeInterceptor" />
        </websocket:handshake-interceptors>
    </websocket:handlers>
    <!-- 注册 sockJS,sockJs是spring对不能使用websocket协议的客户端提供一种模拟 -->
    <websocket:handlers>
        <websocket:mapping path="/sockjs/websocket" handler="msgHandler" />
        <websocket:handshake-interceptors>
            <ref bean="handshakeInterceptor" />
        </websocket:handshake-interceptors>
        <websocket:sockjs />
    </websocket:handlers>
</beans>

握手拦截器,继承HttpSessionHandshakeInterceptor类,做一些连接握手或者握手后的一些处理

public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {

    // 握手前
    @Override
    public boolean beforeHandshake(ServerHttpRequest request,
            ServerHttpResponse response, WebSocketHandler wsHandler,
            Map<String, Object> attributes) throws Exception {

        System.out
                .println("++++++++++++++++ HandshakeInterceptor: beforeHandshake  ++++++++++++++"
                        + attributes);

        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    // 握手后
    @Override
    public void afterHandshake(ServerHttpRequest request,
            ServerHttpResponse response, WebSocketHandler wsHandler,
            Exception ex) {

        System.out
                .println("++++++++++++++++ HandshakeInterceptor: afterHandshake  ++++++++++++++");

        super.afterHandshake(request, response, wsHandler, ex);
    }
}

创建MsgWebSocketHandler类继承WebSocketHandler类(Spring提供的有AbstractWebSocketHandler类、TextWebSocketHandler类、BinaryWebSocketHandler类,看自己需要进行继承),该类主要是用来处理消息的接收和发送

public class MsgWebSocketHandler implements WebSocketHandler {

    private Logger logger = LoggerFactory.getLogger(MsgWebSocketHandler.class);

    //保存用户链接
    private static ConcurrentHashMap<String, WebSocketSession> users = new ConcurrentHashMap<String, WebSocketSession>();
  // 连接 就绪时
    @Override
    public void afterConnectionEstablished(WebSocketSession session)
            throws Exception {
        users.put(session.getId(), session);
    }

    // 处理信息
    @Override
    public void handleMessage(WebSocketSession session,
            WebSocketMessage<?> message) throws Exception {
        System.err.println(session + "---->" + message + ":"+ message.getPayload().toString());
    }

    // 处理传输时异常
    @Override
    public void handleTransportError(WebSocketSession session,
            Throwable exception) throws Exception {

    }

    // 关闭 连接时
    @Override
    public void afterConnectionClosed(WebSocketSession session,
            CloseStatus closeStatus) {
        logger.debug("用户: " + session.getRemoteAddress() + " is leaving, because:" + closeStatus);

    }

    //是否支持分包
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}

要进行发送消息的操作,自己可以写方法,利用保存的已经完成连接的WebSocketSession,通过调用sendMessage(WebScoketMessage<?> message)方法进行消息的发送,参数message是发送的消息内容,Spring提供的类型有TextMessage、BinaryMessage、PingMessage、PongMessage。

前端客户端JS

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>websocket</title>
</head>
<style type="text/css">
    #div {
        color: red;
    }
</style>
<body>
    <h1>WEBSOCKET----TEST</h1>
    <div id="div">

    </div>
</script>
<script type="text/javascript">
var div = document.getElementById(‘div‘);
var socket = new WebSocket(‘ws://127.0.0.1:8088/websocket‘); 

socket.onopen = function(event){
    console.log(event);
    socket.send(‘websocket client connect test‘);
}

socket.onclose = function(event){
    console.log(event);
}

socket.onerror = function(event){
    console.log(event);
}

socket.onmessage = function(event){
    console.log(event)
    div.innerHTML += (‘ @[email protected] ‘ + event.data + ‘ ~_~ ‘);
}
</script>
</body>
</html>

其实在后台也可以进行websocket客户端的创建

@Test
    public void connectTest(){
        WsWebSocketContainer wsWebSocketContainer = new WsWebSocketContainer();
        wsWebSocketContainer.setDefaultMaxSessionIdleTimeout(300);
        StandardWebSocketClient client = new StandardWebSocketClient(wsWebSocketContainer);
        WebSocketHandler webSocketHandler = new MyWebSocketHandler();
        String uriTemplate = "ws://127.0.0.1:8088/websocket?account=11111";
        Object uriVars = null;
        ListenableFuture<WebSocketSession> future = client.doHandshake(webSocketHandler, uriTemplate, uriVars);
        try {
            WebSocketSession session = future.get();
            session.sendMessage(new TextMessage("hello world"));
        } catch (InterruptedException | ExecutionException | IOException e) {
            e.printStackTrace();
        }

    }

    @Test
    public void connectTest2(){
        StandardWebSocketClient client = new StandardWebSocketClient();
        WebSocketHandler webSocketHandler = new MyWebSocketHandler();
        String uriTemplate = "ws://127.0.0.1:8088/websocket";
        UriComponentsBuilder fromUriString = UriComponentsBuilder.fromUriString(uriTemplate);
        fromUriString.queryParam("account","111111");
        /*
         * 作用同上,都是将请求参数填入到URI中
         * MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
         * params.add("account","111111");
         * fromUriString.queryParams(params);
         * */
        URI uri = fromUriString.buildAndExpand().encode().toUri();
        WebSocketHttpHeaders headers = null;
        ListenableFuture<WebSocketSession> doHandshake = client.doHandshake(webSocketHandler, headers  , uri);
        try {
            WebSocketSession session = doHandshake.get();
            session.sendMessage(new TextMessage("hello world"));
        } catch (InterruptedException | ExecutionException | IOException e) {
            e.printStackTrace();
        }

    }

这是我利用Junit进行的测试,实验证明是可以完成websocket的连接。

注意:websocket在进行连接的时候是可以类似get请求一样,将参数拼接到url中。还可以自己将参数封装进URI中,利用另一个方法进行连接的握手操作。

原文地址:https://www.cnblogs.com/zzw-blog/p/8530083.html

时间: 2024-10-10 17:52:57

spring对websocket的集成和使用的相关文章

Spring Chapter4 WebSocket 胡乱翻译 (二)

书接上文,Spring Chapter4 WebSocket 胡乱翻译 (一) 4.4.4. 消息流 一旦暴露了STOMP端点,Spring应用程序就成为连接客户端的STOMP代理. 本节介绍服务器端的消息流. Spring-messaging模块包含对源自Spring Integration的消息传递应用程序的基础支持,后来被提取并整合到Spring Framework中,以便在许多Spring项目和应用程序场景中得到更广泛的使用. 下面列出了一些可用的消息传递抽象: Message - 包含

玩转spring boot——websocket

前言 QQ这类即时通讯工具多数是以桌面应用的方式存在.在没有websocket出现之前,如果开发一个网页版的即时通讯应用,则需要定时刷新页面或定时调用ajax请求,这无疑会加大服务器的负载和增加了客户端的流量.而websocket的出现,则完美的解决了这些问题. spring boot对websocket进行了封装,这对实现一个websocket网页即时通讯应用来说,变得非常简单. 一.准备工作 pom.xml引入 <dependency> <groupId>org.springf

Spring之WebSocket网页聊天以及服务器推送

Spring之WebSocket网页聊天以及服务器推送 转自:http://www.xdemo.org/spring-websocket-comet/ /Springframework /Spring之WebSocket网页聊天以及服务器推送 1. WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duplex). 2. 轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客服端

菜鸟学习Spring——60s学会Spring与Hibernate的集成

一.概述. Spring与Hibernate的集成在企业应用中是很常用的做法通过Spring和Hibernate的结合能提高我们代码的灵活性和开发效率,下面我就一步一步的给大家讲述Spring如何和Hibernate集成的. 二.代码演示. 导入Hibernate的jar包 Hibernate-3.2/lib/*.jar Hibernate-3.2/hibernate3.jar 还有导入Spring的相关jar包 我用的数据库是MySql所以要导入MySql的驱动jar包: mysql-conn

Spring+SpringMvc+Mybatis框架集成搭建教程

一.背景 最近有很多同学由于没有过SSM(Spring+SpringMvc+Mybatis , 以下简称SSM)框架的搭建的经历,所以在自己搭建SSM框架集成的时候,出现了这样或者那样的问题,很是苦恼,网络上又没有很详细的讲解以及搭建的教程.闲来无事,我就利用空闲时间来写这样一个教程和搭建步骤,来帮助那些有问题的小伙伴,让你从此SSM搭建不再有问题. 二.教程目录 1.Spring+SpringMvc+Mybatis框架集成搭建教程一(项目创建) 2.Spring+SpringMvc+Mybat

Spring Boot系列——如何集成Log4j2

上篇<Spring Boot系列--日志配置>介绍了Spring Boot如何进行日志配置,日志系统用的是Spring Boot默认的LogBack. 事实上,除了使用默认的LogBack,Spring Boot还可以使用Log4j.Log42等作为自己的日志系统.今天就那Log4j2来举例,说明Spring Boot是如何集成其他日志系统的. 添加jar包依赖 上篇提到过,Spring Boot默认使用LogBack,但是我们没有看到显示依赖的jar包,其实是因为所在的jar包spring-

【ELK】3.spring boot 2.X集成ES spring-data-ES 进行CRUD操作 完整版

spring boot 2.X集成ES 进行CRUD操作  完整版 内容包括: ========================================================================================= 1.CRUD:单字段查询.复合查询.分页查询.评分查询 2.时间范围查询 3.GET方法传入时间类型解析不了的问题 4.term和match查询的区别 5.filter+query查询的区别 6.自定义ES的mapping,自定义setti

深入Spring Boot:快速集成Dubbo + Hystrix

背景Hystrix 旨在通过控制那些访问远程系统.服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力.Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能.Dubbo是Alibaba开源的,目前国内最流行的java rpc框架.本文介绍在spring应用里,怎么把Dubbo和Hystrix结合起来使用.Spring Boot应用生成dubbo集成spring boot的应用配置spring-cloud-starter-netflix-hys

Spring与Web环境集成

1.Spring与Web环境集成 1.1自定义监听器将Spring集成到web环境 1_需求:将spring集成到web开发环境中,将所有的bean对象创建交给spring,除了servlet,servlet可以理解为一个测试类.在servlet中获取ApplicationContext,获取对应的bean 环境搭建,这个是自己一步步取实现的,其实spring有提供简单的方法完成1.1的操作 <!--在pom文件中引入所需的依赖--> <!--Spring坐标--> <dep