zoukankan      html  css  js  c++  java
  • spring(spring mvc)整合WebSocket案例(获取请求参数)

    开发环境(最低版本):spring 4.0+java7+tomcat7.0.47+sockjs

    前端页面要引入:

    <script src="http://cdn.jsdelivr.net/sockjs/1/sockjs.min.js"></script>

    maven依赖:

    <dependency>
                <groupId>org.java-websocket</groupId>
                <artifactId>Java-WebSocket</artifactId>
                <version>1.3.0</version>
            </dependency>
    <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-websocket</artifactId>
                <version>4.3.10.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-messaging</artifactId>
                <version>4.3.10.RELEASE</version>
            </dependency>

    前端js:

    var ws = null;
    function openWebSocket(){
        //判断当前浏览器是否支持WebSocket
        if ('WebSocket' in window) {
            ws = new WebSocket("ws://"+window.location.host+"/项目名称/visualizationWebSocket.do?type=mall");
        } else {
            ws = new SockJS("http://"+window.location.host+"/项目名称/sockjs/visualizationWebSocket/info?type=mall");
        }
        ws.onopen = function () {
    
        };
      //这个事件是接受后端传过来的数据 ws.onmessage
    = function (event) { //根据业务逻辑解析数据 }; ws.onclose = function (event) { }; }

    我实现连接后台的方式如下:

    //页面已加载后加载后台数据
    $(function (){
        $.ajax({
            cache:false,
            data:"",
            type:"post",
            url:"",
            success:function(data, textStatus){
                if(data && data.status === "1"){
                    //这里可以初始化操作
                    openWebSocket();//websocket连接到后台
                    if(ws){
                        setTimeout(function (){
                            ws.send("");//发送信息到后台,开始有数据跟新就写到前端显示
                        },3000);
                    }
                } else {
                    alert("操作失败!");
                }
            },
            error:function(XMLHttpRequest, textStatus, errorThrown){}
        });
        function zeroPadding(num, digit) {
            var zero = '';
            for(var i = 0; i < digit; i++) {
                zero += '0';
            }
            return (zero + num).slice(-digit);
        }
        function showDate() {
            var date = new Date();
            var str = "" + zeroPadding(date.getFullYear(),4) + "-";
            str += zeroPadding((date.getMonth() + 1),2) + "-";
            str += zeroPadding(date.getDate(),2) + "&nbsp;&nbsp;&nbsp;&nbsp;";
            str += zeroPadding(date.getHours(),2) + ':';
            str += zeroPadding(date.getMinutes(),2) + ':';
            str += zeroPadding(date.getSeconds(),2) + '';
            return str;
        }
    
        setInterval(function () {
            $('.data-time').html(showDate)
        }, 1000);
    
    });

    后端:

    webSocket配置

    package com.snw.supplyChain.websocket;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.socket.WebSocketHandler;
    import org.springframework.web.socket.config.annotation.EnableWebSocket;
    import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
    import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
    
    @Configuration
    @EnableWebSocket
    @EnableWebMvc
    public class VisualizationWebSocketConfig implements WebSocketConfigurer {
    
        public void registerWebSocketHandlers(WebSocketHandlerRegistry webSocketHandlerRegistry) {
         //这里的url要与页面的url一致 webSocketHandlerRegistry.addHandler(myHandler(),
    "/visualizationWebSocket.do").addInterceptors(new VisualizationHandshakeInterceptor());
         //至于这里为什么要加info,我遇见的情况是,当我使用sockjs来代替websocket时,连接的后面会自动加上info webSocketHandlerRegistry.addHandler(myHandler(),
    "/sockjs/visualizationWebSocket/info").addInterceptors(new VisualizationHandshakeInterceptor()).withSockJS(); } @Bean public WebSocketHandler myHandler(){ return new VisualizationWebSocketHandler(); } }

    回话拦截器

    package com.snw.supplyChain.websocket;
    
    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 java.util.Map;
    //回话拦截器
    public class VisualizationHandshakeInterceptor extends HttpSessionHandshakeInterceptor {
        @Override
        public boolean beforeHandshake(ServerHttpRequest request,
                                       ServerHttpResponse response, WebSocketHandler wsHandler,
                                       Map<String, Object> attributes) throws Exception {
         //获取请求参数,首先我们要获取HttpServletRequest对象才能获取请求参数;当ServerHttpRequset的层次结构打开后其子类可以获取到我们想要的http对象,那么就简单了。
        //我这里是把获取的请求数据绑定到session的map对象中(attributes) HttpServletRequest servletRequest
    = ((ServletServerHttpRequest) request).getServletRequest(); String id = servletRequest.getSession().getId(); System.out.println("beforeHandshake: "+id); String type = servletRequest.getParameter("type"); attributes.put("mall",type); return super.beforeHandshake(request, response, wsHandler, attributes); } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) { System.out.println("After Handshake"); super.afterHandshake(request, response, wsHandler, ex); } }

    websocket处理器

    处理器里面可以注入想要的service

    package com.snw.supplyChain.websocket;
    
    import com.snw.supplyChain.model.VisualizationProduct;
    import com.snw.supplyChain.service.IVisualizationService;
    import net.sf.json.JSONObject;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.socket.CloseStatus;
    import org.springframework.web.socket.TextMessage;
    import org.springframework.web.socket.WebSocketSession;
    import org.springframework.web.socket.handler.TextWebSocketHandler;
    
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    public class VisualizationWebSocketHandler extends TextWebSocketHandler {
        private static final Map<String,WebSocketSession> sessions = new HashMap<String, WebSocketSession>();
        private static final Map<String,Thread> threads = new HashMap<String, Thread>();
        private  Thread polingVisualization = null;
        //用户标识
        private static final String CLIENT_ID = "sessionId";
        @Autowired
        private IVisualizationService visualizationService;
    
        @Override
        public void afterConnectionEstablished(WebSocketSession session) throws Exception {
            System.out.println("afterConnectionEstablished: 
    "+session.getId());
            Object sessionType = session.getAttributes().get("mall");
            if(sessionType != null && "mall".equals(sessionType)){
                sessions.put(CLIENT_ID,session);
                sessions.put(session.getId(),session);
            }
            super.afterConnectionEstablished(session);
        }
    
        @Override
        public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
            Thread thread = threads.get(session.getId());
            if(thread != null){
                thread.interrupt();
                try {
                    thread.join();
                    threads.remove(session.getId());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            sessions.remove(session.getId());
            sessions.remove(CLIENT_ID);
            polingVisualization = null;
            try {
                super.afterConnectionClosed(session, status);
            } catch (Exception e) {
            }
        }
       //这里是处理前端发送的消息以及返回给前端的数据
        //可以从session里面获取attributes,
        @Override
        protected void handleTextMessage(WebSocketSession session,
                                         TextMessage message) throws Exception {
            super.handleTextMessage(session, message);
            Thread thread = threads.get(session.getId());
            if(thread == null){
               System.out.println("handleTextMessage: 
    "+session.getId());
               WebSocketSession sessi =  sessions.get(session.getId());
               if(sessi == null){
                    sessions.put(session.getId(),session);
               } else {
                   session = sessi;
               }
               final WebSocketSession localSession = session;
               final TextMessage localMessage = message;
                String payload = message.getPayload();
                if(StringUtils.isNotBlank(payload)){
                    String[] split = payload.split("_");
                    if(StringUtils.isNotBlank(split[2])){
                        if("mall".equals(split[1])){
                            final int universalid = Integer.parseInt(split[2]);
                   //这里的Thread可以用java.util.concurrent代替
                            Thread polingVisualization = new Thread(new Runnable() {
                                public void run() {
                                    while(!Thread.currentThread().isInterrupted()){
                                        try {
                                            polingVisualization(localSession, localMessage, universalid);
                                            try {
                                                Thread.sleep(180000);//300000
                                            } catch (InterruptedException e) {
                                                e.printStackTrace();
                                            }
                                        } catch (IOException e) {
                                            e.printStackTrace();
                                        }
                                    }
                                }
                            });
                            polingVisualization.start();
                            threads.put(sessi.getId(),polingVisualization);
                        }
                    }
                }
            }
        }
    
        private VisualizationProduct polingVisualization(WebSocketSession session,
                                         TextMessage message,Integer universalid) throws IOException {
            VisualizationProduct visualizationProduct = visualizationService.findInquiryPriceOrderVisualization(universalid);
            Map<String,Object> dataMap = new HashMap<String, Object>();
            dataMap.put("status","1");
            dataMap.put("visualizationProduct", visualizationProduct);
            String dataStr = JSONObject.fromObject(dataMap).toString();
            TextMessage  returnMessage = new TextMessage(dataStr);
            session.sendMessage(returnMessage);
            return visualizationProduct;
        }
    
        /**
         * 给正在发布的商品发送新数据
         * @param universalid 发布会ID
         * @param sessionId
         */
        public void sendNewProductDatas(Integer universalid, String sessionId){
            if(universalid != null){
                Set<String> keys = sessions.keySet();
                for (String key : keys) {
                    WebSocketSession webSocketSession = sessions.get(key);
                    if(webSocketSession != null && webSocketSession.isOpen()){
                        VisualizationProduct visualizationProduct = visualizationService.findInquiryPriceOrderVisualization(universalid);
                        Map<String,Object> dataMap = new HashMap<String, Object>();
                        dataMap.put("status","1");
                        dataMap.put("visualizationProduct", visualizationProduct);
                        String dataStr = JSONObject.fromObject(dataMap).toString();
                        System.out.println(dataStr);
                        TextMessage returnMessage = new TextMessage(dataStr);
                        try {
                            webSocketSession.sendMessage(returnMessage);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    spring配置文件

    文件标签,根据需要的添加,比如:websocket的xmlns和xsi:schemaLocation

    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:jee="http://www.springframework.org/schema/jee"
           xmlns:websocket="http://www.springframework.org/schema/websocket"
           xmlns:tx="http://www.springframework.org/schema/tx"
           xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
           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/jee http://www.springframework.org/schema/jee/spring-jee.xsd
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
                http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd">
    <!-- 配置好处理器 -->
    <bean id="websocketHandler" class="com.snw.supplyChain.websocket.VisualizationWebSocketHandler"/>
    <!-- 配置拦截器 -->
        <websocket:handlers>
            <websocket:mapping path="/visualizationWebSocket.do" handler="websocketHandler"/><!-- 连接的URL -->
            <websocket:handshake-interceptors>
                <bean class="com.snw.supplyChain.websocket.VisualizationHandshakeInterceptor"/>
            </websocket:handshake-interceptors>
        </websocket:handlers>

    欢迎各位大神指点其中不足哟。

    逻辑处理
  • 相关阅读:
    阅读笔记之梦断代码(二)
    php完成页面跳转并传值
    java 内部类
    阅读笔记之《程序员修炼之道从小工到专家》(一)
    java 反射机制
    微信的研究【转http://blog.csdn.net/chief1985/article/details/7902016】
    Java sending and receiving file (byte[]) over sockets
    Android音频实时传输与播放(四):源码下载(问题更新)【转】
    windows phone 游戏
    Android音频实时传输与播放(三):AMR硬编码与硬解码【转】
  • 原文地址:https://www.cnblogs.com/cunkouzh/p/8041732.html
Copyright © 2011-2022 走看看