WebSocket消息推送

本文介绍了WebSocket协议,它通过HTTP协商后独立运行在TCP上,是持久化协议,能实现全双工通信,可用于聊天室等应用。还纠正了将其与HTML5 WebSocket API混淆的误区,最后展示了用Spring Boot实现WebSocket消息推送的步骤。

WebSocket介绍

什么是WebSocket

WebSocket是一个协议,归属于IETF。

1.HTTP是运行在TCP协议传输层上的应用协议,而WebSocket是通过HTTP协议协商如何连接,然后独立运行在TCP协议传输层上的应用协议。

2.Websocket是一个持久化的协议,相对于HTTP这种非持久的协议来说

3.Websocket约定了一个通信的规范,通过一个握手的机制,客户端和服务器之间能建立一个类似tcp的连接,从而方便它们之间的通信

为什么需要WebSocket

添加WebSocket特性,是为了更好、更灵活,轻量的与服务器通讯。因为WebSocket提供了简单的消息规范,可以更快的适应长连接的环境,其实现在HTTP协议自身就可以做,但是不太轻便。

WebSocket最大的特点就是实现全双工通信:客户端能够实时推送消息给服务端,服务端也能够实时推送消息给客户端。

WebSocket可以做聊天室,股票实时价格显示等应用

纠正WebSocket误区

WebSocket是一种应用协议,而我们常常看到了HTML5 WebSocket是API,不要将其进行混淆。

广义上的 HTML5 里面包含的是 WebSocket API,并不是 WebSocket。简单的说,可以把 WebSocket 当成 HTTP,WebSocket API 当成 Ajax。

现在我们来用spring boot来使用webSocket实现消息推送

1.首先我们引用Spring-boot所带的websocket依赖

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
复制代码

2.编写前端代码和后台处理后台触发的事件

<script>
    var websocket = null;
    if('WebSocket' in window){
        websocket = new WebSocket('ws://localhost:80/websocket');
    }else{
        alert("该浏览器不支持WebSocket");
    }
 
    websocket.onopen = function (event) {
        console.log("建立连接");
    }
 
    websocket.onclose = function (event) {
        console.log("断开连接");
    }
 
    websocket.onmessage = function (event) {
        console.log("收到消息" + event.data);
        //弹框
        $('#myModal').modal('show');
        //播放音乐
        document.getElementById('notice').play();
    }
 
    websocket.onerror = function (event) {
        alert("websocket通信发生错误");
    }
 
    window.onbeforeunload = function (event) {
        websocket.close();
    }
</script>
复制代码

3. 使用配置WebSocket部署在Spring容器中

@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
} 
复制代码

注:这个Bean会自动使用@ServerEndpoint注解声明的Websocket dedpoint,要注意,如果独立使用Servlet容器,而不是直接使用Spring Boot的内置容器就不需要注入ServerEndpontExporter,因为它将由容器自己提供和管理。

4.编写WebSocket具体的实现类

@ServerEndpoint(value = "/websocket")
@Component
@Slf4j
public class MyWebSocket {
   
    //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中
        log.info("有新连接加入!当前连接人数" + webSocketSet.size());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        webSocketSet.remove(this);  //从set中删除
        log.info("关系连接,当前连接人数" + webSocketSet.size());
    }

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

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

     /**
     * 发送消息
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }
}
复制代码

注:使用SpringBoot的唯一区别在于是在@Componet声明下,而使用独立的容器来管理Websocket,但是在springboot中连容器都是Spring管理的,虽然@Componet默认是单例模式 的,但是SpringBoot还是为每个WebSocket Session连接初始化一个Bean,所以可以用一个线程安全的Set进行保存起来。

以上是WebSocket消息推送的列子,启动你的 Spring Boot 的 Application 程序,并在不同浏览器中打开你的 html 文件,查看 Web Socket 的效果。


转载于:https://juejin.im/post/5c91adb26fb9a070e937bbb3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值