springboot使用websocket推送消息(spring)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
package cc.datebook.socketSpring;

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

import javax.servlet.http.HttpSession;
import java.util.Map;

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

    private static final String SESSION_USER = "user";

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
                                   WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        //解决The extension [x-webkit-deflate-frame] is not supported问题
        if (request.getHeaders().containsKey("Sec-WebSocket-Extensions")) {
            request.getHeaders().set("Sec-WebSocket-Extensions", "permessage-deflate");
        }
        if (request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;
            HttpSession session = serverHttpRequest.getServletRequest().getSession();
            if (session != null) {
                attributes.put(SESSION_USER, session.getAttribute(SESSION_USER));//request.getSession().setAttribute(SESSION_USER, User);
            }
        }
        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);
    }
}
package cc.datebook.socketSpring;

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 {

@Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new SocketHandler(), "/webSocket/spring").addInterceptors(new HandshakeInterceptor()).setAllowedOrigins("*");
        registry.addHandler(new SocketHandler(), "/sockJs/webSocket").addInterceptors(new HandshakeInterceptor()).withSockJS();
    }
}
package cc.datebook.socketSpring;

import cc.datebook.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

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

    private static final Logger logger = LoggerFactory.getLogger(SocketHandler.class);
    //在线用户列表
    private static final Map<Integer, WebSocketSession> users = new HashMap<>();
    //用户标识
    private static final String SESSION_USER = "user";
    /**
     * 在WebSocket协商成功后调用,并且打开WebSocket连接准备使用
     * @param webSocketSession
     * @throws Exception 异常
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession webSocketSession)throws IOException {
        logger.info("成功建立连接");
        Integer userId = getUserId(webSocketSession);
        if (userId != null) {
            users.put(userId, webSocketSession);
            webSocketSession.sendMessage(new TextMessage("成功建立socket连接"));
        }
    }

    /**
     * 处理收到的webSocketMessage
     *
     * @param webSocketSession
     * @param webSocketMessage
     * @throws Exception
     */
    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) {
        logger.info(webSocketSession+":"+webSocketMessage.getPayload());
    }

    /**
     * 处理来自底层WebSocket消息传输的错误
     * @param webSocketSession
     * @param throwable 错误
     * @throws Exception 异常
     */
    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
        if (webSocketSession.isOpen()) {
            webSocketSession.close();
        }
        //移除异常用户信息
        users.remove(getUserId(webSocketSession));
    }

    /**
     * 在网络套接字连接关闭后或在传输错误发生后调用。
     * 尽管从技术上讲,会话可能仍然是开放的,但取决于底层实现,在这一点上发送消息是不鼓励的,而且很可能不会成功。
     * @param webSocketSession webSocketSession
     * @param closeStatus closeStatus
     * @throws Exception 异常
     */
    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
        if (webSocketSession.isOpen()) {
            webSocketSession.close();
        }
        users.remove(getUserId(webSocketSession));
        System.out.println("安全退出了系统");
    }

    /**
     * WebSocketHandler是否处理部分消息
     * @return 标志
     */
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 发送信息给指定用户
     * @param userId
     * @param message
     * @return
     */
    public static boolean sendMessageToUser(Integer userId, String message) {
        if (users.get(userId) == null) {
            return false;
        }
        WebSocketSession session = users.get(userId);
        if (!session.isOpen()) {
            return false;
        }
        try {
            session.sendMessage(new TextMessage(message));
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 广播信息
     * @param message
     * @return
     */
    public static boolean sendMessageToAllUsers(String message) {
        boolean allSendSuccess = true;
        Set<Integer> clientIds = users.keySet();
        WebSocketSession session = null;
        for (Integer clientId : clientIds) {
            try {
                session = users.get(clientId);
                if (session.isOpen()) {
                    session.sendMessage(new TextMessage(message));
                }
            } catch (IOException e) {
                e.printStackTrace();
                allSendSuccess = false;
            }
        }
        return  allSendSuccess;
    }

    /**
     * 获取用户id
     * @param session
     * @return
     */
    private Integer getUserId(WebSocketSession session) {
        try {
            User userBean = (User) session.getAttributes().get(SESSION_USER);
            return userBean.getId();
        } catch (Exception e) {
            return null;
        }
    }
}

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));
    }) ;

});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值