1. 程式人生 > >springMvc中websokect的應用例項

springMvc中websokect的應用例項

1.需要用到的jar包

spring-websocket-4.0.5.RELEASE.jar

2.配置config檔案:

spring-websocket.xml

內容:

<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:mvc="http://www.springframework.org/schema/mvc"
    xmlns:websocket="http://www.springframework.org/schema/websocket"
    xsi:schemaLocation="http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/websocket   
        http://www.springframework.org/schema/websocket/spring-websocket.xsd">
        
        <bean id="websocket" class="com.xiangya.web.filter.WebSocketHandler"/>

<websocket:handlers>
    <websocket:mapping path="/websocket" handler="websocket"/>
    <websocket:handshake-interceptors>
   <bean class="com.xiangya.web.filter.HandShakeInterceptor"/>
   </websocket:handshake-interceptors>
</websocket:handlers>
        <websocket:handlers>
    <websocket:mapping path="/socket" handler="websocket"/>
    <websocket:handshake-interceptors>
   <bean class="com.xiangya.web.filter.HandShakeInterceptor"/>
   </websocket:handshake-interceptors>
   <websocket:sockjs/>
</websocket:handlers>
 </beans>

3.配置web.xml

在web.xml中新增

  <servlet>  
        <servlet-name>websocket</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
         <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath*:/config/spring-websocket.xml</param-value>
    </init-param>
     <async-supported>true</async-supported>
    </servlet>  
    <servlet-mapping>  
        <servlet-name>websocket</servlet-name>  
        <url-pattern>/websocket</url-pattern>
        <url-pattern>/socketjs/*</url-pattern>    
    </servlet-mapping>  

另外在<filter></filter>中新增  <async-supported>true</async-supported>

4.建立握手處理的類,和訊息處理的類

握手處理的類:

  public class HandShakeInterceptor extends HttpSessionHandshakeInterceptor {
@Override
public boolean beforeHandshake(ServerHttpRequest request,
ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
//握手前
       if (request instanceof ServletServerHttpRequest) {
           ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
           HttpSession session = servletRequest.getServletRequest().getSession(false);
           // 標記使用者
           Integer id = (Integer) session.getAttribute("id");
           if(id!=null){
               attributes.put("id", id);
           }else{
               return false;
           }
       }
       return true;
}


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

}
}

訊息處理的類

public class WebSocketHandler extends TextWebSocketHandler {
public static  Map<Integer,WebSocketSession> DOCTORONLINE=new HashMap<Integer,WebSocketSession>();
@Override
protected void handleTextMessage(WebSocketSession session,TextMessage message) throws Exception {
super.handleTextMessage(session, message);
Integer userId=null;
if(message.getPayload()!=null&&message.getPayload()!=""){
userId=Integer.parseInt(message.getPayload());
}
if(DOCTORONLINE.get(userId)==null){
DOCTORONLINE.put(userId, session);
}
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
System.out.println("Websocket:" + session.getId() + "已經關閉");
        Iterator<Entry<Integer, WebSocketSession>> it = DOCTORONLINE.entrySet().iterator();
        // 移除Socket會話
        while (it.hasNext()) {
            Entry<Integer, WebSocketSession> entry = it.next();
            if (entry.getValue().getId().equals(session.getId())) {
            DOCTORONLINE.remove(entry.getKey());
                System.out.println("Socket會話已經移除:使用者ID" + entry.getKey());
                break;
            }
        }
}
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// TODO Auto-generated method stub
super.afterConnectionEstablished(session);
Integer id=(Integer)session.getAttributes().get("id");
//將訊息推送給這個專家
if(DOCTORONLINE.get(id)==null){
DOCTORONLINE.put(id, session);
}

}
@Override
protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {
// TODO Auto-generated method stub
super.handlePongMessage(session, message);
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
// TODO Auto-generated method stub
super.handleTransportError(session, exception);
//資訊傳輸時出錯的處理
if (session.isOpen()) {
           session.close();
       }
       Iterator<Entry<Integer, WebSocketSession>> it = DOCTORONLINE.entrySet().iterator();
       // 移除Socket會話
       while (it.hasNext()) {
           Entry<Integer, WebSocketSession> entry = it.next();
           if (entry.getValue().getId().equals(session.getId())) {
            DOCTORONLINE.remove(entry.getKey());
               System.out.println("Socket會話已經移除:使用者ID" + entry.getKey());
               break;
           }
       }
}
@Override
public boolean supportsPartialMessages() {
// TODO Auto-generated method stub
return false;
}
//傳送資訊給專家
public void sendMessageToDoctor(Integer doctorId, Integer id) throws Exception{
//訊息編號必須存在
if(id!=null&&id>=0){
//找到指定的專家doctorId
WebSocketSession session=DOCTORONLINE.get(doctorId);
if(session!=null&&session.isOpen()){
TextMessage textMessage=new TextMessage(String.valueOf(id));
//將訊息推送給這個專家
session.sendMessage(textMessage);
}
}
 }
}

5.controller中

將id 儲存在session中


在index.jsp頁面 websocket的使用

 var connectCount=0;
var socketFlg=0;

function connect() {  
if (window.location.protocol == 'http:') {
                  url = 'ws://' + window.location.host+urlPath;
              } else {
                  url = 'wss://' + window.location.host + urlPath;
              }
if ('WebSocket' in window) {
  ws = new WebSocket(url);
           } else if ('MozWebSocket' in window) {
            ws  = new MozWebSocket(url);
           } else {
            ws  = new SockJS("http://"+window.location.host+urlPath1);
socketFlg=1;
           }
            ws.onopen = function () {
if(socketFlg==1){
ws.send(userId);
}
            };
            ws.onmessage = function (event) {
省略無關程式碼
            };
            ws.onclose = function (event) {
socketFlg=0;
            if(connectCount<20){
            setTimeout("connect()",5000);
            connectCount++;
            }else{
            window.location.href="index.html";
            }
            };
ws.onerror = function (event) {
window.location.href="index.html";
            };
 }  
var ws = null;
         var url = "";
         var urlPath="";
         var urlPath1="";
         var connectCount=0;
var socketFlg=0;
         if(window.location.pathname.indexOf("xiangya")>-1){
        urlPath="/xiangya"+"/websocket";
        urlPath1="/xiangya"+"/socketjs/socket";
         }else{
        urlPath="/websocket";
        urlPath1="/socketjs/socket";
         }
connect();



6.補充說明websokect的原理

http://blog.csdn.net/yinqingwang/article/details/52565133

http://blog.csdn.net/frank_good/article/details/50856585

相關推薦

springMvcwebsokect應用例項

1.需要用到的jar包 spring-websocket-4.0.5.RELEASE.jar 2.配置config檔案: spring-websocket.xml 內容: <beans xmlns="http://www.springframework.org/sch

Fiddler在APP測試工作應用例項

1、輔助定位bug 場景:在APP介面輸入資料,點選下一步時,提示錯誤;這時候不能判斷問題的根本原因在哪裡,是前端頁面作限制導致? 1.1、例項–APP抓包 前提:APP、fiddler在同一區域網 1.1.1、fiddler設定   Tools>Options>Connecti

JWT學習(二):JWT在分散式SSO應用例項

上一篇文章講解了JWT的基本簡介,這一篇文章我就來實戰一下。介紹一下在分散式單點登入中的使用方法: 首先來看一下Token實體類, public class Token implements Serializable{ private static final lo

反射應用進階篇之自定義反射工具類在springmvc應用

本篇使用自定義工具類進行批量處理物件 ---將批量源物件的屬性值注入到實際需要的目標類物件(屬性名相同,型別不同)中 專案使用maven構建war工程:  spring+spring MVC+Mybatis 回顧知識點: 事務:--->為什麼在使用AOP時需要使

javaEE之------SpringMVCParameterMethodNameResolver應用

介紹 方法動態呼叫核心類org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver 正在學習SpringMV

SpringMvcModelAndView模型的應用

gpo view new date() spring 添加 post return c中 /** * 目標方法的返回值可以是 ModelAndView 類型。 * 其中可以包含視圖和模型信息 * SpringMVC 會把 ModelAndView 的 model

SpringMVCPojo作為引數的應用

首先在頁面新增一個表單. <form action="springmvc/testPojo" method="post"> <input type="text" name="username" /> <br>

.NETQuartz任務排程器的簡單應用例項

1.首先從NuGet中安裝Quartz,安裝最新版本就OK 2.新建一個Job類實現Quart中的IJob介面用於執行業務邏輯,程式碼如下: class CheckUpdateJob : IJob { public async Task Exec

Springmvc+Redis應用例項

第一步: 建立maven專案: 例項pom.xml內容如下 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/

JQuery應用例項學習 —— 16 節點包裹input框與li標籤字型加粗

 jQuery包結點 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

C++引用(&)的用法和應用例項

對於習慣使用C進行開發的朋友們,在看到c++中出現的&符號,可能會犯迷糊,因為在C語言中這個符號表示了取地址符,但是在C++中它卻有著不同的用途,掌握C++的&符號,是提高程式碼執行效率和增強程式碼質量的一個很好的辦法。在 c++學習提高篇(3)---隱式

Alias 例項: 使用表名稱別名(在SQL應用

Alias 可以為列名稱和表名稱指定別名 表的SQL  alias語法 Select column_name(s) from table_name AS alias_name 列的SQL alias 語法 Select  column_name AS alias_na

javaMap集合的常用遍歷方法及HashMap的應用例項

Map的遍歷大體有3種: 1、遍歷Map.entrySet():它的每一個元素都是Map.Entry物件,這個物件中, 放著的就是Map中的某一對key-value; 2、遍歷Map.keySet():它是Map中key值的集合,我們可以通過遍歷這個集合來 讀取M

javaMongoDB的簡單應用例項

1 首先載入 MongoDB的jar包。下載Jar包連結 2然後進行相應的配置。如我當前專案是在web-pom.xml 的的節點下配置。 <dependency> <groupId>org.mo

springmvc 專案完整示例01 需求與資料庫表設計 簡單的springmvc應用例項 web專案

一個簡單的使用者登入系統 使用者有賬號密碼,登入ip,登入時間 開啟登入頁面,輸入使用者名稱密碼 登入日誌,可以記錄登陸的時間,登陸的ip 成功登陸了的話,就更新使用者的最後登入時間和ip,同時記錄一條登入記錄 大致就是這樣子 ----------------------- 建立資料庫 n

js陣列的find、filter、forEach、map四個方法的詳解和應用例項

陣列中的find、filter、forEach、map四個語法很相近,為了方便記憶,真正的掌握它們的用法,所以就把它們總結在一起嘍。find():返回通過測試的陣列的第一個元素的值在第一次呼叫 callback 函式時會確定元素的索引範圍,因此在 find 方法開始執行之後新

電源設計的電容應用例項

電源往往是我們在電路設計過程中最容易忽略的環節。其實,作為一款優秀的設計,電源設計應當是很重要的,它很大程度影響了整個系統的效能和成本。   這裡,只介紹一下電路板電源設計中的電容使用情況。這往往又是電源設計中最容易被忽略的地方。很多人搞ARM,搞DSP,搞FPGA,乍一

C++學習筆記(四)C++友元friend的用法和應用例項

C++中的友元機制允許類的非公有成員被一個類或者函式訪問,友元按型別分為三種: (1)普通非類成員函式作為友元 (2)類的成員函式作為友元 (3)類作為友元。 友元包括友元的宣告以及友元的定義。友元

springmvc應用通用入口路由匹配

package com.dstech.dssp.httpclient.control; import com.dstech.dssp.base.user.User; import com.dstech.dssp.control.WebUser; import com.dst

C++引用(&)的用法和應用例項(相當經典!!!)

對於習慣使用C進行開發的朋友們,在看到c++中出現的&符號,可能會犯迷糊,因為在C語言中這個符號表示了取地址符,但是在C++中它卻有著不同的用途,掌握C++的&符號,是提高程式碼執行效率和增強程式碼質量的一個很好的辦法。引用是C++引入的新語言特性,是C++常