千家信息网

SpringMVC中怎么开放WebSocket接口

发表于:2025-02-05 作者:千家信息网编辑
千家信息网最后更新 2025年02月05日,这篇文章给大家介绍SpringMVC中怎么开放WebSocket接口,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1、配置WebSocket接口信息。1)首先创建websocke
千家信息网最后更新 2025年02月05日SpringMVC中怎么开放WebSocket接口

这篇文章给大家介绍SpringMVC中怎么开放WebSocket接口,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

1、配置WebSocket接口信息。

1)首先创建websocket专属的package(规范问题,实现某一功能的源码应放到统一路径下)。

2)创建WebSocketConfig类,继承WebMvcConfigurationSupport类,实现WebSocketConfigurer接口并实现其定义的方法。添加类注解

@Configuration
@EnableWebMvc
@EnableWebSocket

3)实现的registerWebSocketHandlers方法中,使用参数WebSocketHandlerRegistry的对象开放WebSocket接口。

registry.addHandler(websocket消息处理实现类实例,websocket地址).setAllowedOrigins("*").addInterceptors(拦截器实例);

其中setAllowedOrigins为设置访问权限,通常不限制访问时使用"*";addInterceptors为添加拦截器,如果不需要拦截器则可不调用此方法。

通常开放WebSocket接口开放两个,因浏览器支持的问题,前端只能使用SockJS插件实现WebSocket连接,所以我们还要开放一个专为SockJS服务的WebSocket接口,只需调用withSockJS接口即可。

registry.addHandler(websocket消息处理实现类实例,websocket地址).setAllowedOrigins("*").addInterceptors(拦截器实例).withSockJS();

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

2、自定义WebSocket消息处理实现。

1)创建WebSocket消息处理接口,继承WebSocketHandler接口(为开放操作接口给其他服务调用,一般与业务相关,服务端希望推送消息时调用此接口,同样关乎规范,亦可使用其他方式实现)。

2)创建WebSocket消息处理实现类,实现第一步创建的接口。其中,业务接口请自行实现,从WebSocketHandler继承实现的接口有:

afterConnectionEstablished:建立WebSocket连接成功时触发。

handleMessage:收到客户端发送的消息时触发。

handleTransportError:发生异常时触发。

afterConnectionClosed:与客户端断开连接时触发。

supportsPartialMessages:是否支持部分消息处理(一般返回false,此标志一般用来拆分大型或未知大小的WebSocket消息,当支持部分消息时,一个消息会拆分成多个消息调用handleMessage,可以利用WebSocketMessage的isLast方法判断是否最后一次消息)。

3、自定义WebSocket消息拦截器(可选)

1)创建WebSocket拦截器,实现HandshakeInterceptor接口。实现方法有:

beforeHandshake:消息处理前。

afterHandshake:消息处理后。

4、将WebSocket配置实例装入Spring容器

此处使用配置扫描包的形式,在配置文件中添加

其中base-package可以根据自己项目的实际包路径配置。

下面就是实例代码,细节处可根据实际项目修改:

  • 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@EnableWebSocketpublic 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消息处理接口实现

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> 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;        //建立连接发送的用户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 list = webSocketMap.get(msgStr);        //判断集合是否为空        if (CollectionUtils.isNotEmpty(list)) {            list.add(session);        } else {            list = new ArrayList();            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 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;    }    /**     * 给单个用户发送消息     *      * @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);        }    }    /**     * 发送链接成功消息     *      * @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("---------发送链接成功消息-----------");        TextMessage outMsg = new TextMessage("");        session.sendMessage(outMsg);    }    @Override    public void sendMessage(Long userId, Integer num) {        //获取用户下的session集合        List list = webSocketMap.get(NumberUtils.num2Str(userId));        //向每一条session中发送数据        if (CollectionUtils.isNotEmpty(list)) {            for (WebSocketSession webSocketSession : list) {                try {                    sendMessage(webSocketSession, num);                } catch (IOException e) {                    throw new ServiceException("发送消息失败");                }            }        }    }}
  • 拦截器

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 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 拦截器  握手后------------");    }}
  • 扫描包配置

        

关于SpringMVC中怎么开放WebSocket接口就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

0