springboot使用websocket推送消息(spring)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import java.util.Map;

/**
 * @author wong
 * @description 前端页面与后台通信握手拦截器, 可用于完善定向发送信息功能。
 */
@Component
public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor {

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                   WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        //将用户信息放入WebSocketSession的属性当中,以便定向发送消息。
        Long userId = 1L;
        attributes.put("WEBSOCKET_USERID", userId);
        //解决The extension [x-webkit-deflate-frame] is not supported问题
        if (request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
            request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");
        }
        return super.beforeHandshake(request, response, wsHandler, attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
                               WebSocketHandler wsHandler,
                               Exception ex) {
        super.afterHandshake(request, response, wsHandler, ex);
    }
}

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * @author wong
 * @description webSocket配置类,绑定前端连接端点url及其他信息
 */
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

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

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        //绑定前端连接端点url
        registry.addHandler(new SocketHandler(), "/webSocket/spring").addInterceptors(new HandshakeInterceptor()).withSockJS();
    }
}

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.util.ArrayList;

/**
 * @author wong
 * @description webSocket处理类
 */
@Component
public class SocketHandler implements WebSocketHandler {

    private static final Logger logger = LoggerFactory.getLogger(SocketHandler.class);

    private static final ArrayList<WebSocketSession> users;

    static {
        users = new ArrayList<>();
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession){
        logger.info("WebSocket连接已建立!");
        //此处可添加客户端接收用户
        logger.info(webSocketSession.getAttributes().get("WEBSOCKET_USERID").toString());
        users.add(webSocketSession);
    }

    /**
     * 给指定用户发送信息
     *
     * @param webSocketSession
     * @param webSocketMessage
     * @throws Exception
     */
    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage){
        //获取指定用户ID
        Long userId = (Long) webSocketSession.getAttributes().get("WEBSOCKET_USERID");
        String message;
        logger.info("处理推送的消息");
        //判断客户端是否消息发送,不需要客户端与客户端的单向通信,此处可省略。
        if (!webSocketMessage.getPayload().equals("undefined")) {
            message = "client 发送的消息为:" + webSocketMessage.getPayload();
        } else {
            message = "推送测试信息 ---" + System.currentTimeMillis();
        }
        sendMessageToUser(userId, new TextMessage(message));
    }

    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
        if (webSocketSession.isOpen()) webSocketSession.close();
        logger.error("系统WebSocket传输错误,连接关闭!用户ID:" + webSocketSession.getAttributes().get("WEBSOCKET_USERID"), throwable);
        //移除异常用户信息
        users.remove(webSocketSession);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {

    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 发送消息
     *
     * @param userId    接收用户
     * @param message 消息
     */

    public static void sendMessageToUser(Long userId, TextMessage message) {
        for (WebSocketSession user : users) {
            if (user.getAttributes().get("WEBSOCKET_USERID").equals(userId)) {
                sendSocketSessionMsg(user, message);
            }
        }
    }

    /**
     * 发送消息
     *
     * @param webSocketSession    接收用户
     * @param message 消息
     */
    private static boolean sendSocketSessionMsg(WebSocketSession webSocketSession, TextMessage message) {
        String msg = message.getPayload();
        boolean sendSuccess = true;
        try {
            if (webSocketSession.isOpen()) {
                synchronized (webSocketSession) {
                    webSocketSession.sendMessage(message);
                }
            } else {
                logger.error("WebSocket连接未打开,系统消息推送失败:" + msg);
                sendSuccess = false;
            }
        } catch (Exception e) {
            logger.error("系统消息推送失败:" + msg, e);
            sendSuccess = false;
        }
        return sendSuccess;
    }
}
require(["jquery","formUtil"], function ($) {

    var url = 'ws://localhost:8090/项目名/webSocket/spring';
    var ws = new WebSocket(url);
    ws.onopen = function(e){
        // ws.send('hello');
    };

    ws.onmessage = function(e) {
        alert(e.data);
    };

    ws.onerror = function(e) {
        alert(e);
    };

    $('body').one('DOMNodeRemoved','#start-help',function (e) {//执行一次以后,自动销毁监听事件
        ws.close();
    });

    $('#help-submit').on('click',function () {
        var formData = $('#help-form').serializeJson();
        ws.send(JSON.stringify(formData));
    }) ;

});

猜你喜欢

转载自blog.csdn.net/wangh92/article/details/81004480