Springboot集成WebSocket实现前端进度条实时显示

前言:本大大找了两天,看了无数篇帖子,大多都是东扯扯,西扯扯,完全看不懂;最后万户从中一点绿,总算找到能运作的写法。因为找不到原文,在这里先感谢那位大佬!!!

一、配置

package com.linkstec.tad.rakuraku.common.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {

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

}

二、后端具体代码实现

package com.linkstec.tad.rakuraku.common.message.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.annotation.PostConstruct;
import javax.websocket.CloseReason;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.linkstec.tad.rakuraku.common.bean.BaseInfo;
import com.linkstec.tad.rakuraku.common.message.service.WebSocketService;

@Component
@ServerEndpoint("/webSocket/{userName}") // encoders = { ServerEncoder.class },可选值,指定编码转换器,传输对象时用到,这里直接转json就ok
public class WebSocketController {

    private static final Map<String, Session> TOKEN_SESSION = new HashMap<>();
    private static final Map<String, String> SESSION_ID_TOKEN = new HashMap<>();
    private static final Map<String, String> SESSION_MESSAGE = new HashMap<>();
    // private static final SimpleDateFormat FORMAT = new SimpleDateFormat("yyyy:MM:dd hh:mm:ss");

    @Autowired
    private WebSocketService webSocketService;

    private static WebSocketController webSocketController;

    @PostConstruct
    public void refreshDate() {
        webSocketController = this;
        webSocketController.webSocketService = this.webSocketService;
    }

    @OnOpen
    public void onOpen(Session session, @PathParam(value = "userName") String userName) {
        System.out.println("新的连接进来了- " + session.getId());
        if (userName == null) {
            try {
                session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "username参数为空"));
            } catch (IOException e) {
                throw new IllegalStateException(e.getMessage());
            }
        } else {
            String uuid = UUID.randomUUID().toString();
            String token = userName + uuid;
            SESSION_ID_TOKEN.put(session.getId(), token);
            TOKEN_SESSION.put(token, session);
            System.out.println(token);
        }
    }

    @OnClose
    public void onColse(Session session) {
        System.out.println("断开连接:" + session.getId() + "-" + SESSION_ID_TOKEN.get(session.getId()));
    }

    @OnMessage
    public void onMessage(Session session, String message) {
        System.out.println("收到客户端发来的消息:" + message + session.getId());
        SESSION_MESSAGE.put(session.getId(), message);
        Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(() -> {
            sendMessage(session, message);
        }, 1000, 1000, TimeUnit.MILLISECONDS);

    }

    @OnError
    public void error(Session session, Throwable t) {
        t.printStackTrace();
    }

    public void sendMessage(Session session, String message) {
        System.out.println("发送全体消息");
        BaseInfo baseInfo = (BaseInfo) JSONObject.toJavaObject(JSON.parseObject(message), BaseInfo.class);
        Integer percentage = webSocketController.webSocketService.initialService(baseInfo);
        sendMessageToTarget(SESSION_ID_TOKEN.get(session.getId()), percentage + "");
        // TOKEN_SESSION.values().forEach((session) -> {
        // session.getAsyncRemote().sendText(message);
        // });
    }

    public <T> void sendMessageToTarget(String token, Object t) {
        System.out.println("发送指定token消息");
        try {
            TOKEN_SESSION.get(token).getBasicRemote().sendText((String) t);
            if (Integer.valueOf(100).equals(t)) {
                Session session = TOKEN_SESSION.get(token);
                session.close(new CloseReason(CloseReason.CloseCodes.CANNOT_ACCEPT, "工程下载完成!"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

三、前端vue + element ui

 downLoadProject(row, index) {
      localStorage.setItem("COMMON.RUNTIME.PRJTID", row.projectId);
      localStorage.setItem("COMMON.RUNTIME.PRJTCASEID", row.projectCaseId);
      localStorage.setItem("COMMON.RUNTIME.STAGEID", row.stageId);
      console.log("row", row);
      var str = row.projectId;
      if (typeof WebSocket === "undefined") {
        alert("您的浏览器不支持socket");
      } else {
        // 实例化socket
        this.socket = new WebSocket(this.path);
        // 监听socket连接
        this.socket.onopen = this.open;
        // 监听socket错误信息
        this.socket.onerror = this.error;
        // 监听socket消息
        this.socket.onmessage = this.getMessage;
        this.socket.onclose = this.close;
      }
    },
    open: function () {
      let params = {
        projectId: localStorage.getItem("COMMON.RUNTIME.PRJTID"),
        projectCaseId: localStorage.getItem("COMMON.RUNTIME.PRJTCASEID"),
        stageId: localStorage.getItem("COMMON.RUNTIME.STAGEID"),
      };
      this.socket.send(JSON.stringify(params));
      console.log("socket连接成功");
    },
    error: function (err) {
      console.log("连接错误" + err);
    },
    getMessage: function (msg) {
      console.log(msg);
      this.msg = msg.data;
    },
    close: function (event) {
      console.log("socket已经关闭" + event.reason);
    },

    sendMessage() {
      this.socket.send(this.sendMsg);
    },

四、具体实现图 

打印出来的msg对象中的data属性就是想要拿取的下载文件的进度!!!!

哦耶耶耶耶耶耶耶耶耶耶! 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
实现Spring Boot集成WebSocket实现消息推送,需要进行以下步骤: 1. 添加Spring Boot WebSocket依赖 2. 创建WebSocket配置类 3. 创建WebSocket处理器类 4. 创建WebSocket拦截器类 5. 创建WebSocket消息模型类 6. 在Spring Boot中使用WebSocket 下面是一个简单的示例代码: 1. 添加Spring Boot WebSocket依赖 在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 2. 创建WebSocket配置类 创建一个WebSocket配置类,用于配置WebSocket相关的参数,如下所示: ``` @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(new WebSocketHandler(), "/websocket").addInterceptors(new WebSocketInterceptor()); } } ``` 3. 创建WebSocket处理器类 创建一个WebSocket处理器类,用于处理WebSocket连接、断开连接和接收消息等操作,如下所示: ``` public class WebSocketHandler extends TextWebSocketHandler { private static final List<WebSocketSession> sessions = new CopyOnWriteArrayList<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { sessions.add(session); } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { sessions.remove(session); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { for (WebSocketSession s : sessions) { s.sendMessage(message); } } } ``` 4. 创建WebSocket拦截器类 创建一个WebSocket拦截器类,用于拦截WebSocket连接请求,如下所示: ``` public class WebSocketInterceptor implements HandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { } } ``` 5. 创建WebSocket消息模型类 创建一个WebSocket消息模型类,用于封装WebSocket消息,如下所示: ``` public class WebSocketMessage { private String content; public String getContent() { return content; } public void setContent(String content) { this.content = content; } } ``` 6. 在Spring Boot中使用WebSocketSpring Boot中使用WebSocket非常简单,只需要在Controller中注入WebSocketSession即可,如下所示: ``` @Controller public class WebSocketController { @Autowired private WebSocketSession session; @MessageMapping("/send") public void send(WebSocketMessage message) throws Exception { session.sendMessage(new TextMessage(message.getContent())); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值