• 三步学会使用WebSocekt


    目录

    一 什么是websocket

    二 如何使用websocket

    1.导入websocket的maven坐标

    2.创建websocket的服务类 

    3.创建websocket的配置类

    4.按需求实现业务逻辑

    5.前端实现websocket


    一 什么是websocket

            websocket和HTTP一样是基于TCP的一个通信协议。不过他是支持客户端和服务端双向通信的协议 。

            和HTTP不同的是,websocket是长连接 , HTTP是短连接 ,因为websocket只要客户端可服务端建立好了连接,除了主动关闭连接 , 他们发送完信息不会自动断开 , 而HTTP客户端向服务端发送一次连接,服务端返回后,就会断开连接 , 下次再发就要重新建立连接。

            而且HTTP只能是客户端主动向服务端发送信息 , 服务端接收,然后再返回。而websockt的服务端和客户端的通信是双向的,客户端可以主动向服务端发送信息 , 服务端也可以主动向客户端发送信息。

    二 如何使用websocket

    1.导入websocket的maven坐标

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-websocketartifactId>
    4. dependency>

    2.创建websocket的服务类 

    1. package com.sky.websocket;
    2. import org.springframework.stereotype.Component;
    3. import javax.websocket.OnClose;
    4. import javax.websocket.OnMessage;
    5. import javax.websocket.OnOpen;
    6. import javax.websocket.Session;
    7. import javax.websocket.server.PathParam;
    8. import javax.websocket.server.ServerEndpoint;
    9. import java.util.Collection;
    10. import java.util.HashMap;
    11. import java.util.Map;
    12. /**
    13. * WebSocket服务
    14. */
    15. @Component
    16. @ServerEndpoint("/ws/{sid}") //连接路径
    17. public class WebSocketServer {
    18. //存放会话对象
    19. private static Map sessionMap = new HashMap();
    20. /**
    21. * 连接建立成功调用的方法
    22. */
    23. @OnOpen
    24. public void onOpen(Session session, @PathParam("sid") String sid) {
    25. System.out.println("客户端:" + sid + "建立连接");
    26. sessionMap.put(sid, session);
    27. }
    28. /**
    29. * 收到客户端消息后调用的方法
    30. *
    31. * @param message 客户端发送过来的消息
    32. */
    33. @OnMessage
    34. public void onMessage(String message, @PathParam("sid") String sid) {
    35. System.out.println("收到来自客户端:" + sid + "的信息:" + message);
    36. }
    37. /**
    38. * 连接关闭调用的方法
    39. *
    40. * @param sid
    41. */
    42. @OnClose
    43. public void onClose(@PathParam("sid") String sid) {
    44. System.out.println("连接断开:" + sid);
    45. sessionMap.remove(sid);
    46. }
    47. /**
    48. * 群发
    49. *
    50. * @param message
    51. */
    52. public void sendToAllClient(String message) {
    53. Collection sessions = sessionMap.values();
    54. for (Session session : sessions) {
    55. try {
    56. //服务器向客户端发送消息
    57. session.getBasicRemote().sendText(message);
    58. } catch (Exception e) {
    59. e.printStackTrace();
    60. }
    61. }
    62. }
    63. }

    ① 你可以把这个类看成一个websocket的Controller类,因为前端页面(客户端)会设置一个连接服务端websocket的路径,就是

    @ServerEndpoint("/ws/{sid}")  //连接路径

    这个路径,需要和前端保持一致。

    ② 然后连接成功之后 , 就会创建一个连接对象 , 把客户端连接对象存储到

    private static Map sessionMap = new HashMap();

    ③ 这个map集合中,String就是上面的{sid}这个参数是前端传来的,作为对象的标识。

    剩下的

    onOpen()

    方法上面加了注解 , 只要客户端与服务端连接成功 , 就会自动调用这个方法。

    ④ 还有下面这个方法

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

    这个方法是收到客户端发送的信息(页面) ,就会自动调用这个方法 , 同时把客户端的标识已经客户端发送的信息当作参数传来。

    ⑤ 还有这个关闭连接的方法

    /**
     * 连接关闭调用的方法
     *
     * @param sid
     */
    @OnClose
    public void onClose(@PathParam("sid") String sid) {
        System.out.println("连接断开:" + sid);
        sessionMap.remove(sid);
    }

    这个方法是在我们关闭连接的时候自动执行。

    ⑥ 最后一个方法

    public void sendToAllClient(String message) {
        Collection sessions = sessionMap.values();
        for (Session session : sessions) {
            try {
                //服务器向客户端发送消息
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    这个方法上面没有任何注解 , 也就是说不能自动执行 , 需要我们调用才会执行 , 他的主要作用就是服务端向客户端发送信息 , 而且我们可以按照需求 , 在不同的逻辑下按需要调用这个方法,来向客户端发送信息 。而且这里是群发 ,因为我是直接遍历map集合中的所有客户端对象进行发送。

    3.创建websocket的配置类

    1. package com.sky.config;
    2. import org.springframework.context.annotation.Bean;
    3. import org.springframework.context.annotation.Configuration;
    4. import org.springframework.web.socket.server.standard.ServerEndpointExporter;
    5. /**
    6. * WebSocket配置类,用于注册WebSocket的Bean
    7. */
    8. @Configuration
    9. public class WebSocketConfiguration {
    10. @Bean
    11. public ServerEndpointExporter serverEndpointExporter() {
    12. return new ServerEndpointExporter();
    13. }
    14. }

    这个配置类主要用于创建websocket的Bean来做一些初始化

    4.按需求实现业务逻辑

            在这里websocket基本配置已经完成了,最后只需要按照自己业务需求去与客户端进行通信就可以了 ,我在这里做一个示例:

            比如我需要每3秒向客户端发送当前时间的信息,而客户端可以主动向服务端发送信息。

            所以这里我就需要使用定时任务springTask来实现这个业务逻辑,每3秒调用向客户端发送信息的方法。实现代码如下:

    1. package com.sky.task;
    2. import com.sky.websocket.WebSocketServer;
    3. import org.springframework.beans.factory.annotation.Autowired;
    4. import org.springframework.scheduling.annotation.Scheduled;
    5. import org.springframework.stereotype.Component;
    6. import java.time.LocalDateTime;
    7. import java.time.format.DateTimeFormatter;
    8. @Component
    9. public class WebSocketTask {
    10. @Autowired
    11. private WebSocketServer webSocketServer;
    12. /**
    13. * 通过WebSocket每隔5秒向客户端发送消息
    14. */
    15. @Scheduled(cron = "0/5 * * * * ?")
    16. public void sendMessageToClient() {
    17. webSocketServer.sendToAllClient("这是来自服务端的消息:" + DateTimeFormatter.ofPattern("HH:mm:ss").format(LocalDateTime.now()));
    18. }
    19. }

     

    5.前端实现websocket

            前端也需要实现websocket相关代码,但是代码都是一样的 , 所以我这里直接将我的前端代码给大家展示出来:

    1. HTML>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>WebSocket Demotitle>
    6. head>
    7. <body>
    8. <input id="text" type="text" />
    9. <button onclick="send()">发送消息button>
    10. <button onclick="closeWebSocket()">关闭连接button>
    11. <div id="message">
    12. div>
    13. body>
    14. <script type="text/javascript">
    15. var websocket = null;
    16. var clientId = Math.random().toString(36).substr(2);
    17. //判断当前浏览器是否支持WebSocket
    18. if('WebSocket' in window){
    19. //连接WebSocket节点
    20. websocket = new WebSocket("ws://localhost:8080/ws/"+clientId);
    21. }
    22. else{
    23. alert('Not support websocket')
    24. }
    25. //连接发生错误的回调方法
    26. websocket.onerror = function(){
    27. setMessageInnerHTML("error");
    28. };
    29. //连接成功建立的回调方法
    30. websocket.onopen = function(){
    31. setMessageInnerHTML("连接成功");
    32. }
    33. //接收到消息的回调方法
    34. websocket.onmessage = function(event){
    35. setMessageInnerHTML(event.data);
    36. }
    37. //连接关闭的回调方法
    38. websocket.onclose = function(){
    39. setMessageInnerHTML("close");
    40. }
    41. //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    42. window.onbeforeunload = function(){
    43. websocket.close();
    44. }
    45. //将消息显示在网页上
    46. function setMessageInnerHTML(innerHTML){
    47. document.getElementById('message').innerHTML += innerHTML + '
      '
      ;
    48. }
    49. //发送消息
    50. function send(){
    51. var message = document.getElementById('text').value;
    52. websocket.send(message);
    53. }
    54. //关闭连接
    55. function closeWebSocket() {
    56. websocket.close();
    57. }
    58. script>
    59. html>

     最终演示结果如下:

    以上就是websocket的基本使用 , 主要代码都是一样的,使用时直接cv即可,只需要实现自己的需求逻辑这部分代码。

  • 相关阅读:
    域名列入备案黑名单解除教程
    leetcode-LCP 06. 拿硬币
    c++基础语法之内联函数
    杭州动环监控系统供应商,动环监控设备
    CVPR‘15 Joint action recognition and pose estimation from video
    JAVA开发中的Maven搭建以及相关操作
    网络程序通信的流程
    集合—Collections工具类
    [附源码]java毕业设计书店网站论文
    [附源码]Python计算机毕业设计SSM开放式实验室预约系统(程序+LW)
  • 原文地址:https://blog.csdn.net/m0_63624484/article/details/140123432