`
liuxing87327
  • 浏览: 82151 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

使用spring4.x的websocket支持

阅读更多

J2EE7版(JSR-356) 

Java Websocket示例

 

 

相关依赖请参考上文,spring需要4.x

 

1、websocket处理器

import org.apache.commons.collections.MapUtils;
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.WebSocketHandler;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.BinaryWebSocketHandler;
import org.springframework.web.socket.handler.TextWebSocketHandler;

/**
 * 功能说明:WebSocket处理器
 * 可以继承 {@link TextWebSocketHandler}/{@link BinaryWebSocketHandler},
 * 或者简单的实现{@link WebSocketHandler}接口
 * 作者:liuxing(2015-01-25 03:42)
 */
public class TelWebSocketHandler extends TextWebSocketHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(TelWebSocketHandler.class);

    /**
     * 建立连接
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String inquiryId = MapUtils.getString(session.getAttributes(), "inquiryId");
        int empNo = MapUtils.getInteger(session.getAttributes(), "empNo");
        TelSocketSessionUtils.add(inquiryId, empNo, session);
    }

    /**
     * 收到客户端消息
     * @param session
     * @param message
     * @throws Exception
     */
    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String inquiryId = MapUtils.getString(session.getAttributes(), "inquiryId");
        int empNo = MapUtils.getInteger(session.getAttributes(), "empNo");
        TelSocketSessionUtils.sendMessage(inquiryId, empNo, "【来自服务器的复读机】:" + message.getPayload().toString());
    }

    /**
     * 出现异常
     * @param session
     * @param exception
     * @throws Exception
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        String inquiryId = MapUtils.getString(session.getAttributes(), "inquiryId");
        int empNo = MapUtils.getInteger(session.getAttributes(), "empNo");

        LOGGER.error("websocket connection exception: " + TelSocketSessionUtils.getKey(inquiryId, empNo));
        LOGGER.error(exception.getMessage(), exception);

        TelSocketSessionUtils.remove(inquiryId, empNo);
    }

    /**
     * 连接关闭
     * @param session
     * @param closeStatus
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
        String inquiryId = MapUtils.getString(session.getAttributes(), "inquiryId");
        int empNo = MapUtils.getInteger(session.getAttributes(), "empNo");
        TelSocketSessionUtils.remove(inquiryId, empNo);
    }

    /**
     * 是否分段发送消息
     * @return
     */
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }

}

 

2、websocket连接的拦截器

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

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

/**
 * 功能说明:websocket连接的拦截器
 * 有两种方式
 *          一种是实现接口HandshakeInterceptor,实现beforeHandshake和afterHandshake函数
 *          一种是继承HttpSessionHandshakeInterceptor,重载beforeHandshake和afterHandshake函数
 * 我这里是参照spring官方文档中的继承HttpSessionHandshakeInterceptor的方式
 * 作者:liuxing(2015-01-25 03:46)
 */
public class TelWebSocketHandshakeInterceptor extends HttpSessionHandshakeInterceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(TelWebSocketHandshakeInterceptor.class);

    /**
     * 从请求中获取唯一标记参数,填充到数据传递容器attributes
     * @param serverHttpRequest
     * @param serverHttpResponse
     * @param wsHandler
     * @param attributes
     * @return
     * @throws Exception
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        if (getSession(serverHttpRequest) != null) {
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) serverHttpRequest;
            HttpServletRequest request = servletRequest.getServletRequest();
            attributes.put("inquiryId", request.getParameter("inquiryId"));
            attributes.put("empNo", request.getParameter("empNo"));
        }

        super.beforeHandshake(serverHttpRequest, serverHttpResponse, wsHandler, attributes);

        return true;
    }

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

    private HttpSession getSession(ServerHttpRequest request) {
        if (request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest serverRequest = (ServletServerHttpRequest) request;
            return serverRequest.getServletRequest().getSession(false);
        }
        return null;
    }

}

 

3.session工具类

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 功能说明:TelSocketSessionUtils
 * 作者:liuxing(2014-12-26 02:32)
 */
public class TelSocketSessionUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(TelSocketSessionUtils.class);

    private static Map<String, WebSocketSession> clients = new ConcurrentHashMap<>();

    /**
     * 保存一个连接
     * @param inquiryId
     * @param empNo
     * @param session
     */
    public static void add(String inquiryId, int empNo, WebSocketSession session){
        clients.put(getKey(inquiryId, empNo), session);
    }

    /**
     * 获取一个连接
     * @param inquiryId
     * @param empNo
     * @return
     */
    public static WebSocketSession get(String inquiryId, int empNo){
        return clients.get(getKey(inquiryId, empNo));
    }

    /**
     * 移除一个连接
     * @param inquiryId
     * @param empNo
     */
    public static void remove(String inquiryId, int empNo) throws IOException {
        clients.remove(getKey(inquiryId, empNo));
    }

    /**
     * 组装sessionId
     * @param inquiryId
     * @param empNo
     * @return
     */
    public static String getKey(String inquiryId, int empNo) {
        return inquiryId + "_" + empNo;
    }

    /**
     * 判断是否有效连接
     * 判断是否存在
     * 判断连接是否开启
     * 无效的进行清除
     * @param inquiryId
     * @param empNo
     * @return
     */
    public static boolean hasConnection(String inquiryId, int empNo) {
        String key = getKey(inquiryId, empNo);
        if (clients.containsKey(key)) {
            return true;
        }

        return false;
    }

    /**
     * 获取连接数的数量
     * @return
     */
    public static int getSize() {
        return clients.size();
    }

    /**
     * 发送消息到客户端
     * @param inquiryId
     * @param empNo
     * @param message
     * @throws Exception
     */
    public static void sendMessage(String inquiryId, int empNo, String message) throws Exception {
        if (!hasConnection(inquiryId, empNo)) {
            throw new NullPointerException(getKey(inquiryId, empNo) + " connection does not exist");
        }

        WebSocketSession session = get(inquiryId, empNo);
        try {
            session.sendMessage(new TextMessage(message));
        } catch (IOException e) {
            LOGGER.error("websocket sendMessage exception: " + getKey(inquiryId, empNo));
            LOGGER.error(e.getMessage(), e);
            clients.remove(getKey(inquiryId, empNo));
        }
    }

}

 

4.初始化配置

    可以使用注解或xml风格

 

<!--websocket配置-->
    <bean id="telWebSocketHandler" class="包.websocket.handler.TelWebSocketHandler"/>

    <websocket:handlers allowed-origins="*">
        <websocket:mapping path="webSocketStatus" handler="telWebSocketHandler"/>
        <websocket:handshake-interceptors>
            <bean class="包.websocket.interceptor.TelWebSocketHandshakeInterceptor"/>
        </websocket:handshake-interceptors>
    </websocket:handlers>

    <bean class="org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean">
        <property name="maxTextMessageBufferSize" value="8192"/>
        <property name="maxBinaryMessageBufferSize" value="8192"/>
        <property name="maxSessionIdleTimeout" value="900000"/>
        <property name="asyncSendTimeout" value="5000"/>
    </bean>

 

spring官方文档已经写得很齐全了,更多场景和说明请参阅下文大笑

http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#websocket

分享到:
评论

相关推荐

    spring4.x________

    2. WebSocket支持:Spring 4.x引入了WebSocket支持,通过STOMP(Simple Text Oriented Messaging Protocol)协议提供实时双向通信,极大地增强了Web应用程序的交互性。 3. RESTful增强:Spring MVC提供了更好的...

    精通Spring4.x+企业应用开发实战 配套光盘(源码+资源)

    8. **WebSocket支持**:Spring4.x引入了对WebSocket协议的支持,允许开发实时通信的应用,例如聊天室、股票报价等。 9. **消息传递**:Spring4.x集成了JMS(Java消息服务),支持消息驱动的架构,允许异步处理和...

    spring4.x.x中文文档

    同时,Spring 4.x.x也加强了对WebSocket的支持,使得实时通信成为可能,这对于构建富客户端应用和实时数据传输的应用场景非常有利。 Spring MVC作为Spring框架的一部分,也在4.x.x版本中得到了增强。它引入了更强大...

    精通Spring4.x企业应用开发实战pdf+源码

    在Spring4.x版本中,框架引入了更多的新特性,如对Java 8的支持、WebSocket集成、反应式编程模型的Spring Reactor等,这些都极大地增强了Spring的灵活性和适用性。 在企业应用开发中,Spring框架的主要知识点包括:...

    Spring4.X+Quartz2.X

    Spring4.X版本引入了一些新特性,比如对Java 8的全面支持、WebSocket支持以及对RESTful服务的改进,这使得它在现代应用开发中更具吸引力。Quartz2.X则提供了更稳定、更灵活的调度机制,支持集群和分布式环境。 **...

    精通Spring 4.x 企业应用开发实战

    Spring 4.0引入了众多Java开发者翘首以盼的基于Groovy Bean的配置、HTML 5/WebSocket支持等新功能,全面支持Java 8.0,*低要求是Java 6.0。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是Java Web应用...

    Spring4.x最新jar包

    2. **WebSocket支持**:Spring 4.x增强了对WebSocket协议的支持,提供了WebSocket消息传递和STOMP(Simple Text Oriented Messaging Protocol)协议的集成,使得实时通信变得更加简单。 3. **Reactive编程**:...

    spring4.x源码

    除此之外,Spring4.x加强了与其他技术的集成,如WebSocket、JMS、JPA等。通过源码,我们可以学习到Spring如何优雅地整合这些技术,为开发者提供统一的API和管理方式。 总的来说,通过深入研究Spring4.x的源码,不仅...

    Spring+3.x企业应用开发实战光盘源码,保证可用

    9. **WebSocket支持**:Spring 3.x开始支持WebSocket协议,为实时通信提供了基础。 通过光盘源码,读者可以深入学习如何配置Spring容器,创建bean,实现依赖注入,以及如何利用Spring的AOP和MVC特性构建实际的企业...

    Spring4.x官方中文文档

    Spring4.x版本的主要更新包括对Java 8的全面支持、WebSocket支持、反应式编程模型的引入以及对异步处理的优化等。以下将详细阐述这些关键知识点。 1. **Java 8支持**: Spring4.x全面拥抱Java 8,提供了对新特性如...

    精通spring4.x代码

    在Spring4.x中,Spring MVC框架集成了WebSocket支持,使得开发实时通信应用变得更加容易。Spring框架提供了`WebSocketMessageBroker`,可以方便地实现消息代理,实现服务器推送功能。 5. **简化Web MVC配置** ...

    精通Spring 4.x 企业应用开发实战高清版

    其次,Spring 4.x对Java EE 7的支持更加完善,包括对WebSocket的集成,这使得实时通信成为可能。书中会介绍如何配置WebSocket端点,以及使用STOMP协议进行消息传递,这对于构建现代Web应用至关重要。 此外,Spring ...

    Spring4.x官网jar文件

    4. **WebSocket支持**:Spring4.x增强了对WebSocket协议的支持,提供了一套完整的服务器端和客户端API,方便构建实时通信应用。 5. **JPA 2.1支持**:对于数据访问,Spring4.x增强了对Java Persistence API (JPA) ...

    精通Spring 4.X:企业应用开发实战精通 (陈雄华) 完整版

    Spring 4.x还加强了对WebSocket的支持,允许实时双向通信,这对于构建现代的富客户端应用至关重要。书中会介绍如何集成WebSocket,实现服务器推送功能。 安全方面,Spring Security是Spring框架的一个重要组件,它...

    精通Spring 4.x企业应用开发实战_源码

    7. **WebSocket支持**:Spring 4.x引入了对WebSocket协议的支持,允许开发实时双向通信的应用。 8. **异步处理**:Spring 4.x增强了对异步编程的支持,包括@Async注解和TaskExecutor,提升了系统性能。 9. **...

    精通Spring 4.x 企业应用开发实战 pdf 附source

    在Spring 4.x版本中,该框架进行了诸多优化和增强,例如对Java 8的支持,改进的RESTful服务构建,以及更强大的WebSocket功能。 首先,书中详细讲解了Spring的核心概念——依赖注入(DI),它是Spring框架的基础。...

    Spring4.x jar包

    8. **WebSocket支持**: Spring4.x引入了对WebSocket协议的支持,使得实时双向通信成为可能,适合构建聊天应用、实时通知等。 9. **Java 8兼容性**: Spring4.x开始全面支持Java 8的新特性,如Lambda表达式和日期时间...

    spring5.x+springmvc5.x+mybatis3.5x+tomcat9+jdk8+maven 项目框架搭建 1.1版本

    Spring MVC 5.x支持WebSocket,增强了HTTP响应式编程,并且与Spring Boot的集成更加紧密。 3. **MyBatis 3.5.x**: MyBatis是一个持久层框架,它将SQL语句与Java代码解耦,通过XML或注解来映射Java对象和数据库...

Global site tag (gtag.js) - Google Analytics