spring boot Websocket

本文只作为个人笔记,大部分代码是引用其他人的文章的。

在springboot项目中使用websocket做推送,虽然挺简单的,但初学也踩过几个坑,特此记录。


  使用websocket有两种方式:1是使用sockjs,2是使用h5的标准。使用Html5标准自然更方便简单,所以记录的是配合h5的使用方法。

1、pom

  核心是@ServerEndpoint这个注解。这个注解是Javaee标准里的注解,tomcat7以上已经对其进行了实现,如果是用传统方法使用tomcat发布项目,只要在pom文件中引入javaee标准即可使用。

复制代码

    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-api</artifactId>
      <version>7.0</version>
      <scope>provided</scope>
    </dependency>

复制代码

  但使用springboot的内置tomcat时,就不需要引入javaee-api了,spring-boot已经包含了。使用springboot的websocket功能首先引入springboot组件。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>

  顺便说一句,springboot的高级组件会自动引用基础的组件,像spring-boot-starter-websocket就引入了spring-boot-starter-web和spring-boot-starter,所以不要重复引入。

2、使用@ServerEndpoint创立websocket endpoint

  首先要注入ServerEndpointExporter,这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint。要注意,如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理。

复制代码

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

}

复制代码

  接下来就是写websocket的具体实现类,很简单,直接上代码:

复制代码

复制代码

@ServerEndpoint(value = "/websocket")
@Component
public class MyWebSocket {
    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketSet.add(this);     //加入set中
        addOnlineCount();           //在线数加1
        System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
        try {
            sendMessage(CommonConstant.CURRENT_WANGING_NUMBER.toString());
        } catch (IOException e) {
            System.out.println("IO异常");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  //从set中删除
        subOnlineCount();           //在线数减1
        System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("来自客户端的消息:" + message);

        //群发消息
        for (MyWebSocket item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 发生错误时调用
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }


    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
        //this.session.getAsyncRemote().sendText(message);
    }


    /**
     * 群发自定义消息
     * */
    public static void sendInfo(String message) throws IOException {
        for (MyWebSocket item : webSocketSet) {
            try {
                item.sendMessage(message);
            } catch (IOException e) {
                continue;
            }
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        MyWebSocket.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        MyWebSocket.onlineCount--;
    }
}

复制代码

复制代码

使用springboot的唯一区别是要@Component声明下,而使用独立容器是由容器自己管理websocket的,但在springboot中连容器都是spring管理的。

虽然@Component默认是单例模式的,但springboot还是会为每个websocket连接初始化一个bean,所以可以用一个静态set保存起来。

3、前端代码

   

复制代码

<!DOCTYPE HTML>
<html>
<head>
    <title>My WebSocket</title>
</head>

<body>
Welcome<br/>
<input id="text" type="text" /><button οnclick="send()">Send</button>    <button οnclick="closeWebSocket()">Close</button>
<div id="message">
</div>
</body>

<script type="text/javascript">
    var websocket = null;

    //判断当前浏览器是否支持WebSocket
    if('WebSocket' in window){
        websocket = new WebSocket("ws://localhost:8084/websocket");
    }
    else{
        alert('Not support websocket')
    }

    //连接发生错误的回调方法
    websocket.onerror = function(){
        setMessageInnerHTML("error");
    };

    //连接成功建立的回调方法
    websocket.onopen = function(event){
        setMessageInnerHTML("open");
    }

    //接收到消息的回调方法
    websocket.onmessage = function(event){
        setMessageInnerHTML(event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function(){
        setMessageInnerHTML("close");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function(){
        websocket.close();
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML){
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //关闭连接
    function closeWebSocket(){
        websocket.close();
    }

    //发送消息
    function send(){
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</html>

复制代码

 

  4、总结

  springboot已经做了深度的集成和优化,要注意是否添加了不需要的依赖、配置或声明。由于很多讲解组件使用的文章是和spring集成的,会有一些配置,在使用springboot时,由于springboot已经有了自己的配置,再这些配置有可能导致各种各样的异常。

参考 https://www.cnblogs.com/bianzy/p/5822426.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Spring Boot WebSocketSpring Boot框架的一个模块,用于在Web应用程序中支持WebSocket协议。它提供了一组简单的配置和使用方式,使得开发人员可以轻松地在Web应用程序中使用WebSocket。可以通过Spring Boot的自动配置特性来配置和使用WebSocket,也可以通过Spring提供的注解和API来更灵活地控制WebSocket的工作方式。 ### 回答2: Spring boot websocket 是一种新型的应用程序通信方式,通过客户端和服务器端之间的实时双向通信,支持实时性强、交互性高的应用场景,可以为用户提供更加稳定、高效和安全的应用使用体验。 Spring boot websocket 是基于一种名为 WebSocket 的网络协议来实现的,并且在 Spring boot 中集成了对 WebSocket 的支持,使得开发者可以更加方便地实现 WebSocket 功能。它的主要特点有以下几点: 1. 实时性强:Spring boot websocket 可以实现实时通信,随时更新信息。 2. 双向通信:Spring boot websocket 可以实现双向通信,客户端与服务器端可以相互发送信息。 3. 交互性高:Spring boot websocket 具有很高的交互性,支持多种数据格式的交互,可以用于在线聊天、游戏、交易等应用场景。 4. 高效性:Spring boot websocket 采用异步消息处理的方式来实现通信,从而保证通信的高效性。 Spring boot websocket 的应用场景非常广泛,比如可以应用于在线多人游戏、在线聊天、数据监控、实时交易等领域。由于 Spring boot websocket 具有实时性强、交互性高、可扩展性强、安全性好等特点,因此在目前的互联网应用场景中越来越受到重视。 总之,Spring boot websocket 是一种先进的应用程序通信方式,能够为用户带来更加丰富、高效、安全的应用体验,拥有广泛的应用前景和发展潜力。 ### 回答3: Spring Boot WebSocket是什么? Spring Boot WebSocket是一种基于WebSocket协议的通信方式,能够实现前后端实时通讯,使得前端能够实时响应后端的数据推送。WebSocket协议是一种全双工通信协议,通过Web套接字(WebSocket)技术使得浏览器和服务器之间可以建立持久性连接,从而使得前后端实时通讯变成了可能。Spring Boot WebSocket基于Spring Framework提供的WebSocket API实现。 为什么要使用Spring Boot WebSocket? 通过使用Spring Boot WebSocket,开发人员可以实现双向实时通讯的功能。这在一些需要实时通知、实时查询的场景下非常有用。例如:在线聊天、在线游戏等。使用WebSocket通讯相较于传统的HTTP通讯,具有低延迟、实时性强等优势。此外,Spring Boot WebSocket相较于其他实现方式,具有开发简单、易于维护、可扩展等特点,因此越来越多的开发人员和公司选择使用Spring Boot WebSocket。 如何在Spring Boot中实现WebSocket? 在Spring Boot中实现WebSocket通讯,需要使用Spring Framework提供的WebSocket API。首先,需要在pom.xml中添加spring-boot-starter-websocket依赖。然后编写WebSocketConfig类,该类需要继承AbstractWebSocketMessageBrokerConfigurer类,并重写其方法。在该类中配置消息代理、消息端点等信息。在Spring Boot中使用WebSocket也可以通过@EnableWebSocketMessageBroker注解来实现,该注解会隐式注册一个DefaultAnnotationHandlerMapping和一个AnnotationMethodHandlerAdapter,并自动配置WebSocket支持的消息代理。最后,对于消息处理器需要使用@MessageMapping注解进行标注,这样就能够使得框架知道什么方法应该处理什么消息。至此,就已经完成了Spring Boot WebSocket的开发和配置。 总的来说,Spring Boot WebSocket是一种比较优秀的实时通讯技术,通过使用它可以让开发人员实现双向实时通讯。在实际开发中,可以根据实际需求选择使用WebSocket或其他通讯方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

那些年的代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值