spring(spring mvc)整合WebSocket案例(獲取請求參數)

開發環境(最低版本):spring 4.0+java7+tomcat7.0.47+sockjshtml

前端頁面要引入:前端

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

maven依賴:java

<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:git

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

我實現鏈接後臺的方式以下:web

//頁面已加載後加載後臺數據
$(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);

});

後端:ajax

webSocket配置spring

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

回話攔截器apache

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: \n"+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處理器json

處理器裏面能夠注入想要的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: \n"+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: \n"+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>

歡迎各位大神指點其中不足喲。

 

 

邏輯處理
相關文章
相關標籤/搜索