SpringMVC中怎么開放WebSocket接口

這篇文章給大家介紹SpringMVC中怎么開放WebSocket接口,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

創(chuàng)新互聯(lián)2013年至今,是專業(yè)互聯(lián)網(wǎng)技術服務公司,擁有項目成都網(wǎng)站制作、成都做網(wǎng)站、外貿營銷網(wǎng)站建設網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元懷柔做網(wǎng)站,已為上家服務,為懷柔各地企業(yè)和個人服務,聯(lián)系電話:028-86922220

     1、配置WebSocket接口信息。

        1)首先創(chuàng)建websocket專屬的package(規(guī)范問題,實現(xiàn)某一功能的源碼應放到統(tǒng)一路徑下)。

        2)創(chuàng)建WebSocketConfig類,繼承WebMvcConfigurationSupport類,實現(xiàn)WebSocketConfigurer接口并實現(xiàn)其定義的方法。添加類注解

        @Configuration
        @EnableWebMvc
        @EnableWebSocket

        3)實現(xiàn)的registerWebSocketHandlers方法中,使用參數(shù)WebSocketHandlerRegistry的對象開放WebSocket接口。

        registry.addHandler(websocket消息處理實現(xiàn)類實例,websocket地址).setAllowedOrigins("*").addInterceptors(攔截器實例);

        其中setAllowedOrigins為設置訪問權限,通常不限制訪問時使用“*”;addInterceptors為添加攔截器,如果不需要攔截器則可不調用此方法。

        通常開放WebSocket接口開放兩個,因瀏覽器支持的問題,前端只能使用SockJS插件實現(xiàn)WebSocket連接,所以我們還要開放一個專為SockJS服務的WebSocket接口,只需調用withSockJS接口即可。

        registry.addHandler(websocket消息處理實現(xiàn)類實例,websocket地址).setAllowedOrigins("*").addInterceptors(攔截器實例).withSockJS();

        至此,第一步,配置WebSocket信息已完成。

    2、自定義WebSocket消息處理實現(xiàn)。

     1)創(chuàng)建WebSocket消息處理接口,繼承WebSocketHandler接口(為開放操作接口給其他服務調用,一般與業(yè)務相關,服務端希望推送消息時調用此接口,同樣關乎規(guī)范,亦可使用其他方式實現(xiàn))。

      2)創(chuàng)建WebSocket消息處理實現(xiàn)類,實現(xiàn)第一步創(chuàng)建的接口。其中,業(yè)務接口請自行實現(xiàn),從WebSocketHandler繼承實現(xiàn)的接口有:

        afterConnectionEstablished:建立WebSocket連接成功時觸發(fā)。

        handleMessage:收到客戶端發(fā)送的消息時觸發(fā)。

        handleTransportError:發(fā)生異常時觸發(fā)。

        afterConnectionClosed:與客戶端斷開連接時觸發(fā)。

        supportsPartialMessages:是否支持部分消息處理(一般返回false,此標志一般用來拆分大型或未知大小的WebSocket消息,當支持部分消息時,一個消息會拆分成多個消息調用handleMessage,可以利用WebSocketMessage的isLast方法判斷是否最后一次消息)。

    3、自定義WebSocket消息攔截器(可選)

   1)創(chuàng)建WebSocket攔截器,實現(xiàn)HandshakeInterceptor接口。實現(xiàn)方法有:

    beforeHandshake:消息處理前。

    afterHandshake:消息處理后。

    4、將WebSocket配置實例裝入Spring容器

   此處使用配置掃描包的形式,在配置文件中添加<context:component-scan base-package="com.???.???.???.websocket" />

    其中base-package可以根據(jù)自己項目的實際包路徑配置。

    下面就是實例代碼,細節(jié)處可根據(jù)實際項目修改:

  •     WebSocket配置信息

package com.???.???.???.websocket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

/**
 * websocket配置類
 * 
 * @author Heller.Zhang
 * @since 2018年11月8日 上午10:23:04
 */
@Configuration
@EnableWebMvc
@EnableWebSocket
public class MyWebSocketConfig extends WebMvcConfigurationSupport implements WebSocketConfigurer {

    private Logger logger = LoggerFactory.getLogger(MyWebSocketConfig.class);

    /* (non-Javadoc)
     * @see org.springframework.web.socket.config.annotation.WebSocketConfigurer#registerWebSocketHandlers(org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry)
     */
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        logger.debug("----------開始注冊MyWebSocketConfig----------");
        logger.debug("----------注冊普通websocket----------");
        registry.addHandler(msgSocketHandle(), "/websocket/myWebSocketServer").setAllowedOrigins("*");

        logger.debug("----------注冊sockjs/websocket----------");
        registry.addHandler(msgSocketHandle(), "/websocket/sockjs/myWebSocketServer").setAllowedOrigins("*").withSockJS();

    }

    @Bean(name = "myMsgScoketHandle", autowire = Autowire.BY_NAME)
    public MyMsgScoketHandle msgSocketHandle() {
        return new MyMsgScoketHandleImpl();
    }

}
  •     自定義WebSocket消息處理接口

package com.???.???.???.websocket;

import org.springframework.web.socket.WebSocketHandler;

/**
 * websocket消息處理器
 * 
 * @author Heller.Zhang
 * @since 2018年11月13日 下午5:13:20
 */
public interface MyMsgScoketHandle extends WebSocketHandler {

    public void sendMessage(Long userId, Integer num);
}
  • 自定義WebSocket消息處理接口實現(xiàn)

package com.???.???.???.websocket;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

import com.hzsparrow.framework.common.exception.ServiceException;
import com.hzsparrow.framework.utils.JsonUtils;
import com.hzsparrow.framework.utils.NumberUtils;

/**
 * websocket消息處理類
 * 
 * @author Heller.Zhang
 * @since 2018年11月8日 上午11:15:22
 */
public class MyMsgScoketHandleImpl implements MyMsgScoketHandle {

    private Logger logger = LoggerFactory.getLogger(MyMsgScoketHandleImpl.class);

    private ConcurrentMap<String, List<WebSocketSession>> webSocketMap = new ConcurrentHashMap<>();

    public MyMsgScoketHandleImpl() {
        logger.debug("--------init MyMsgScoketHandle-----------");
    }

    /* (non-Javadoc)
     * @see org.springframework.web.socket.WebSocketHandler#afterConnectionEstablished(org.springframework.web.socket.WebSocketSession)
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        logger.debug("-----------建立websocket連接---------");
    }

    /* (non-Javadoc)
     * @see org.springframework.web.socket.WebSocketHandler#handleMessage(org.springframework.web.socket.WebSocketSession, org.springframework.web.socket.WebSocketMessage)
     */
    @Override
    public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
        logger.debug("-----------處理消息---------");
        TextMessage msg = (TextMessage) message;

        //建立連接發(fā)送的用戶id
        String msgStr= msg.getPayload();
        logger.debug("----------msg:" + msgStr);
        if (StringUtils.equals(msgStr, "heartbeat")) {
            // 心跳消息,不予處理
            return;
        }
        session.getAttributes().put("mykey", msgStr + "|" + UUID.randomUUID().toString());
        //通過用戶id獲取session集合
        List<WebSocketSession> list = webSocketMap.get(msgStr);
        //判斷集合是否為空
        if (CollectionUtils.isNotEmpty(list)) {
            list.add(session);
        } else {
            list = new ArrayList<WebSocketSession>();
            list.add(session);
        }

        //將用戶id和session集合綁定到map
        webSocketMap.put(msgStr, list);
        logger.debug("消息處理完畢");

    }

    /* (non-Javadoc)
     * @see org.springframework.web.socket.WebSocketHandler#handleTransportError(org.springframework.web.socket.WebSocketSession, java.lang.Throwable)
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        logger.debug("-----------處理異常---------");
    }

    /* (non-Javadoc)
     * @see org.springframework.web.socket.WebSocketHandler#afterConnectionClosed(org.springframework.web.socket.WebSocketSession, org.springframework.web.socket.CloseStatus)
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        logger.debug("-----------斷開連接---------");
        String myKey = session.getAttributes().get("mykey").toString();
        String userId = myKey.split("|")[0];
        List<WebSocketSession> list = webSocketMap.get(userId);
        WebSocketSession delSession = null;
        if (CollectionUtils.isNotEmpty(list)) {
            for (WebSocketSession webSocketSession : list) {
                String delKey = webSocketSession.getAttributes().get("mykey").toString();
                if (StringUtils.equals(myKey, delKey)) {
                    delSession = webSocketSession;
                    break;
                }
            }
        }
        if (delSession != null) {
            list.remove(delSession);
        }

    }

    /* (non-Javadoc)
     * @see org.springframework.web.socket.WebSocketHandler#supportsPartialMessages()
     */
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

    /**
     * 給單個用戶發(fā)送消息
     * 
     * @param session
     * @param type
     * @param data
     * @throws IOException
     * @author Heller.Zhang
     * @since 2018年11月8日 下午2:05:32
     */
    public void sendMessage(WebSocketSession session, Object data) throws IOException {
        if (session.isOpen()) {
            String json = JsonUtils.serialize(data);
            TextMessage outMsg = new TextMessage(json);
            session.sendMessage(outMsg);
        }
    }

    /**
     * 發(fā)送鏈接成功消息
     * 
     * @param session
     * @throws IOException
     * @author Heller.Zhang
     * @since 2018年11月10日 下午3:16:35
     */
    public void sendSuccessMsg(WebSocketSession session, Integer type) throws IOException {
        logger.debug("---------發(fā)送鏈接成功消息-----------");
        TextMessage outMsg = new TextMessage("");
        session.sendMessage(outMsg);
    }

    @Override
    public void sendMessage(Long userId, Integer num) {
        //獲取用戶下的session集合
        List<WebSocketSession> list = webSocketMap.get(NumberUtils.num2Str(userId));
        //向每一條session中發(fā)送數(shù)據(jù)
        if (CollectionUtils.isNotEmpty(list)) {
            for (WebSocketSession webSocketSession : list) {
                try {
                    sendMessage(webSocketSession, num);
                } catch (IOException e) {
                    throw new ServiceException("發(fā)送消息失敗");
                }
            }
        }

    }

}
  • 攔截器

package com.???.???.???.websocket;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

/**
 * websocket攔截器
 * 
 * @author Heller.Zhang
 * @since 2018年11月8日 上午10:40:51
 */
public class MyWebSocketHandshakeInterceptor implements HandshakeInterceptor {

    private Logger logger = LoggerFactory.getLogger(MyWebSocketHandshakeInterceptor.class);

    /* (non-Javadoc)
     * @see org.springframework.web.socket.server.HandshakeInterceptor#beforeHandshake(org.springframework.http.server.ServerHttpRequest, org.springframework.http.server.ServerHttpResponse, org.springframework.web.socket.WebSocketHandler, java.util.Map)
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
            Map<String, Object> attributes) throws Exception {
        logger.debug("---------websocket 攔截器  握手前------------");
        return true;
    }

    /* (non-Javadoc)
     * @see org.springframework.web.socket.server.HandshakeInterceptor#afterHandshake(org.springframework.http.server.ServerHttpRequest, org.springframework.http.server.ServerHttpResponse, org.springframework.web.socket.WebSocketHandler, java.lang.Exception)
     */
    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
            Exception exception) {
        logger.debug("---------websocket 攔截器  握手后------------");
    }

}
  • 掃描包配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:task="http://www.springframework.org/schema/task" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">

    <context:component-scan base-package="com.???.???.???.websocket" />
    
</beans>

關于SpringMVC中怎么開放WebSocket接口就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

分享標題:SpringMVC中怎么開放WebSocket接口
鏈接URL:http://muchs.cn/article34/jpippe.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供外貿網(wǎng)站建設、定制網(wǎng)站建站公司、標簽優(yōu)化App設計、響應式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化