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分支中)

  

posted @ 2020-04-03 12:38  CodingPanda  阅读(2191)  评论(0编辑  收藏  举报