zoukankan      html  css  js  c++  java
  • SpringBoot接入WebSocket详解(含源码)

    1.实际效果

    2.添加一个WebSocketConfig

    package com.llltony.springboot.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.stereotype.Component;
    import org.springframework.web.socket.server.standard.ServerEndpointExporter;
    
    @Component
    public class WebSocketConfig {
    
        /**
         * ServerEndpointExporter 作用
         *
         * 这个Bean会自动注册使用@ServerEndpoint注解声明的websocket endpoint
         *
         * @return
         */
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    }

    3.添加WebSocket类

    package com.llltony.springboot.socket;
    
    import com.alibaba.fastjson.JSONObject;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    
    import javax.websocket.OnClose;
    import javax.websocket.OnMessage;
    import javax.websocket.OnOpen;
    import javax.websocket.Session;
    import javax.websocket.server.PathParam;
    import javax.websocket.server.ServerEndpoint;
    import java.util.concurrent.ConcurrentHashMap;
    
    /**
     * @ServerEndpoint 这个注解有什么作用?
     * <p>
     * 这个注解用于标识作用在类上,它的主要功能是把当前类标识成一个WebSocket的服务端
     * 注解的值用户客户端连接访问的URL地址
     */
    
    @Slf4j
    @Component
    @ServerEndpoint("/websocket/{name}")
    public class WebSocket {
    
        /**
         * 与某个客户端的连接对话,需要通过它来给客户端发送消息
         */
        private Session session;
    
        /**
         * 标识当前连接客户端的用户名
         */
        private String name;
    
        /**
         * 用于存所有的连接服务的客户端,这个对象存储是安全的
         */
        private static ConcurrentHashMap<String, WebSocket> webSocketSet = new ConcurrentHashMap<>();
    
    
        @OnOpen
        public void OnOpen(Session session, @PathParam(value = "name") String name) {
            this.session = session;
            this.name = name;
            // name是用来表示唯一客户端,如果需要指定发送,需要指定发送通过name来区分
            webSocketSet.put(name, this);
            log.info(name+"[WebSocket] 连接成功,当前连接人数为:={}", webSocketSet.size());
        }
    
    
        @OnClose
        public void OnClose() {
            webSocketSet.remove(this.name);
            log.info(name+"[WebSocket] 退出成功,当前连接人数为:={}", webSocketSet.size());
        }
    
        @OnMessage
        public void OnMessage(String message) {
            log.info("[WebSocket] 收到消息:{}", message);
            //根据用户名判断知道发送
            JSONObject json = JSONObject.parseObject(message);
            String name=json.get("username").toString();
            String content=json.get("content").toString();
            if (!name.equals("") && name!= null) {
                AppointSending(name, content);
            } else {
                GroupSending(message);
            }
        }
    
        /**
         * 群发
         *
         * @param message
         */
        public void GroupSending(String message) {
            for (String name : webSocketSet.keySet()) {
                try {
                    webSocketSet.get(name).session.getBasicRemote().sendText(message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * 指定发送
         *
         * @param name
         * @param message
         */
        public void AppointSending(String name, String message) {
            try {
                webSocketSet.get(name).session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    4.添加pom依赖

    <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-websocket</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
    
            <!-- fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.47</version>
            </dependency>

    5.添加html页面进行调用测试

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>websocket_Test</title>
        <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
        <meta content="no-cache" http-equiv="pragma">
        <meta content="no-cache" http-equiv="cache-control">
        <meta content="0" http-equiv="expires">
        <meta content="keyword1,keyword2,keyword3" http-equiv="keywords">
        <meta content="This is my page" http-equiv="description">
    </head>
    <body>
    <div>
        <h3>testing...</h3>
        <div id="msgtext">
        </div>
        <div>
            <input id="username" name="username" type="text" placeholder="请输入用户名"/>
            <button onclick="connectWebSocket();">连接WebSocket</button>
            <br>
            <input id="msg" name="msg" type="text" placeholder="请输入发生信息"/>
            <button onclick="sendmsg();">发送</button>
        </div>
    </div>
    
    </body>
    <script type="text/javascript">
          var ws;
          function connectWebSocket(){
              if('WebSocket' in window){
                  var url="ws://localhost:8080/websocket/";
                  var username=$('#username').val();
                  if(username=="" || username==null){
                    alert("请输入用户名");
                    return;
                  }else{
                    url=url+username;
                  }
                  ws = new WebSocket(url);
              }else{
                  alert("不支持 websocket");
              }
              ws.onopen = function(evt){
                  //alert("op");
              }
              ws.onclose =function(evt){
                  alert("close");
              }
              ws.onmessage = function(evt){
                  var msg = evt.data;
                  if("[object Blob]" != msg){
                      var msgdiv = document.getElementById("msgtext");
                      var span = document.createElement("span");
                      span.innerHTML = msg+"<br />";
                      msgdiv.appendChild(span);
                  }else{
                      var msgdiv = document.getElementById("msgtext");
                      var span = document.createElement("span");
                      var br = document.createElement("br");
                      var can = document.createElement("canvas");
                      var context = can.getContext("2d");
                      var image = new Image();
                        image.onload = function () {
                    //image.height
                    context.clearRect(0, 0, can.width, can.height);
                    context.drawImage(image, 0, 0, can.width, can.height);
                }
                image.src = URL.createObjectURL(msg);
                span.appendChild(can);
                span.appendChild(br);
                msgdiv.appendChild(span);
                  }
              }
              ws.onerror = function(evt){
                  alert("error");
              }
          }
          function sendmsg(){
              var message={};
              message.content="("+new Date().toLocaleTimeString()+")<br />"+document.getElementById("msg").value;
              message.username=$('#username').val();
              ws.send(JSON.stringify(message));
          }
    
    </script>
    </html>

    6.后端代码里的调用websocket发送消息

    7.源码:https://github.com/CodingPandaLLL/tsl.git(在dev_webSocket分支中)

      

  • 相关阅读:
    第十三节:实际开发中使用最多的监视锁Monitor、lock语法糖的扩展、混合锁的使用(ManualResetEvent、SemaphoreSlim、ReaderWriterLockSlim)
    第十二节:深究内核模式锁的使用场景(自动事件锁、手动事件锁、信号量、互斥锁、读写锁、动态锁)
    第十一节:深究用户模式锁的使用场景(异变结构、互锁、旋转锁)
    第十节:利用async和await简化异步编程模式的几种写法
    第九节:深究并行编程Parallel类中的三大方法 (For、ForEach、Invoke)和几大编程模型(SPM、APM、EAP、TAP)
    C# DataTable列名不区分大小写
    如何很好的使用Linq的Distinct方法
    Java读写记事本文件
    c# 获取方法所在的命名空间 类名 方法名
    C#中类的序列化和反序列化
  • 原文地址:https://www.cnblogs.com/LiLiliang/p/12625783.html
Copyright © 2011-2022 走看看