WebSocket實時異步通信

WebSocket實時異步通信

【一】WebSocket簡介

  WebSocket是HTML5推出一個協議規范,用來B/S模式中服務器端和客戶端之間進行實時異步通信。

  眾所周知,傳統的HTTP協議中,服務器端和客戶端通信只能是在客戶端發送一個請求之后,服務器端才能對其響應,也就是說服務器端是不能夠主動向客戶端發起數據的。

  當在服務器端和客戶端之間需要頻繁地實時通信時,傳統HTTP協議只能通過Ajax輪詢的方式,即客戶端每隔一段時間請求一次服務器來獲得更新,這樣做的對服務器的性能要求特別高,而且占用很多無用的帶寬、流量。

?

?

圖一 傳統HTTP請求會話

圖二 WebSocket請求會話

  WebSocket在實時通信方面很好的彌補了傳統HTTP協議的不足。它是一個建立在HTTP協議之上的協議,通過HTTP建立了WebSocket連接之后,服務器端和客戶端就可以隨時通信了。

?

【二】WebSocket的使用

服務器端

  Tomcat7.0.5版本及以后的版本之中已經內嵌了支持WebSocket標準協議的jar包websocket-api.jar;在服務器端開發中通過@ServerEndpoint注解表明WebSocket服務端運行在 ws://[Server端IP或域名]:[Server端口]/project-name/注解參數值 路徑指定的位置,客戶端在創建WebSocket對象的時候,通過該路徑指定服務器響應的WebSocket。

  @OnOpen@OnClose、@OnError注解WebSocket方法分別響應建立連接、關閉連接和出錯時候的回調函數,@OnMessage注解的方法響應收到客戶端發送數據的回調函數。Session相當于客戶端,可以向客戶端發送數據。

  WebSocket類處理客戶端的所有請求,然后根據不同頁面的請求調用不同的類對象進行處理。

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.websocket.Session;
import org.apache.log4j.Logger;
import net.sf.json.JSONObject;

@ServerEndpoint("/websocket") public class WebSocket {public static Logger log = Logger.getLogger(WebSocket.class); private Statement stmt = null;private Connection conn = null; private Timer timer;@OnOpenpublic void onOpen(Session s) { log.info("client connected");timer = new Timer();//connect databasetry {ResourceBundle config = ResourceBundle.getBundle("config");String driver = config.getString("jdbc.driver");String url = config.getString("jdbc.cfg.url");String username = config.getString("jdbc.cfg.username");String password = config.getString("jdbc.cfg.password");Class.forName(driver);conn = DriverManager.getConnection(url, username, password);stmt = conn.createStatement(); log.info("connect database successful");}catch (ClassNotFoundException e) {e.printStackTrace();}catch (SQLException e) {e.printStackTrace();}}@OnMessagepublic void onMessage(final String message, Session s) throws IOException, InterruptedException{log.info("message="+message);final JSONObject json = JSONObject.fromString(message);if(json.getInt("pageIndex") == 2){ //熱門配置頁不循環推送 HotConfig hotConfig = new HotConfig(s, stmt);hotConfig.sendWebSocket(json);}else if(json.getInt("pageIndex") == 3){final TrafficLog trafficLog = new TrafficLog(s, stmt);int isRealTimeSearch = json.getInt("isRealTimeSearch");if(isRealTimeSearch == 1){timer.schedule(new TimerTask() { //每隔5分鐘執行一次 @Override public void run() {trafficLog.sendWebSocket(json);} }, 0, 300000); }else{ //只執行一次timer.schedule(new TimerTask() {@Override public void run() {trafficLog.sendWebSocket(json);} }, 0); }}else if(json.getInt("pageIndex") == 4){final RuleLog ruleLog = new RuleLog(s, stmt);int isRealTimeSearch = json.getInt("isRealTimeSearch");if(isRealTimeSearch == 1){timer.schedule(new TimerTask() { //每隔5分鐘執行一次 @Override public void run() {ruleLog.sendWebSocket(json);} }, 0, 300000); }else{ //只執行一次timer.schedule(new TimerTask() {@Override public void run() {ruleLog.sendWebSocket(json);} }, 0); }}else{ //isp頁面的請求final ISPLog ispLog = new ISPLog(s, stmt);int isRealTimeSearch = json.getInt("isRealTimeSearch");if(isRealTimeSearch == 1){timer.schedule(new TimerTask() { //每隔5分鐘執行一次 @Override public void run() {ispLog.sendWebSocket(json);} }, 0, 300000); }else{ //只執行一次timer.schedule(new TimerTask() {@Override public void run() {ispLog.sendWebSocket(json);} }, 0); }}}@OnClosepublic void onClose(Session s) {log.info("Client closed");try {timer.cancel(); if (stmt != null) {stmt.close();stmt = null;}if (conn != null) {conn.close();conn = null;}} catch (SQLException e) {e.printStackTrace();}}@OnErrorpublic void onError(Throwable e) {log.error("WebSocket Error");e.printStackTrace();} }


  響應具體某個頁面的請求

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.websocket.Session;
import org.apache.log4j.Logger;
import net.sf.json.JSONObject;public class HotConfig {private Session session;private Statement stmt = null;private ResultSet rs = null;private static Logger log = Logger.getLogger(HotConfig.class);public HotConfig(Session s, Statement stmt){this.session = s;this.stmt = stmt;}public void sendWebSocket(final JSONObject json){String srcIp = json.getString("srcIp");String startTime = json.getString("startTime");String endTime = json.getString("endTime");Map<String, ArrayList<Long>> params = new HashMap<String, ArrayList<Long>>();ArrayList<Long> pzID = new ArrayList<Long>();             //different chart lines nameArrayList<Long> statCount = new ArrayList<Long>();        //chart x axisArrayList<Long> pzIDReverse = new ArrayList<Long>();            //different chart lines nameArrayList<Long> statCountReverse = new ArrayList<Long>();        //chart x axistry {String srcIpCriteria = "";                        //拼接源IP SQL條件if(srcIp.length() > 0) {srcIpCriteria = " where CLIENT_IP='"+srcIp+"' ";}String startTimeCriteria = "";                    //拼接源IP SQL條件if(startTime.length() > 0) {if(srcIpCriteria.equals(""))startTimeCriteria = " where STAT_TIME >= to_date('"+startTime +"','yyyy-mm-dd hh24:mi')";elsestartTimeCriteria = " and STAT_TIME >= to_date('"+startTime +"','yyyy-mm-dd hh24:mi')";}String endTimeCriteria = "";                      //拼接源IP SQL條件if(endTime.length() > 0) {if(srcIpCriteria.equals("") && startTimeCriteria.equals(""))endTimeCriteria = " where STAT_TIME < to_date('" +endTime+"','yyyy-mm-dd hh24:mi') ";elseendTimeCriteria = " and STAT_TIME < to_date('" +endTime+"','yyyy-mm-dd hh24:mi') ";}String sql = "select * from (select PZ_ID, sum(STAT_COUNT) as sumCount from RULE_HOT_CONFIG_INFO" + srcIpCriteria + startTimeCriteria + endTimeCriteria + " group by PZ_ID order by sumCount desc) where rownum <= 50";                log.info("sql="+sql+"execute success");rs = stmt.executeQuery(sql);while(rs.next()){ pzID.add(rs.getLong(1));statCount.add(rs.getLong(2));}for(int i = pzID.size() - 1; i >= 0; i--){pzIDReverse.add(pzID.get(i));statCountReverse.add(statCount.get(i));}params.put("pzID", pzIDReverse);params.put("statCount",statCountReverse);         session.getBasicRemote().sendText(JSONObject.fromBean(params).toString());log.info("主動發給前端的數據="+JSONObject.fromBean(params).toString());} catch (IOException e) {e.printStackTrace();} catch (SQLException e) {e.printStackTrace();}}}

?

客戶端

  目前主流的瀏覽器Firefox、Chrome已經支持WebSocket協議,這意味只不需要引用額外的js庫就可以直接使用WebSocket了。

<script type="text/javascript">   
     //創建WebSocket對象,用于一開始建立連接,之后就不要再建立連接了var webSocket = new WebSocket('ws://localhost:8080/websocket/websocket');webSocket.onopen = function(event) {};webSocket.onmessage = function(event) {
        //接收來自服務器的數據,這里客戶端沒有發送任何請求,任何時間接收到數據都可以異步調用onMessage(event);
        var? m = JSON.parse(event.data);
        alert(m);};webSocket.onerror
= function(event) {}; function onMessage(event) {} </script>

?


?推薦學習文章:http://www.ibm.com/developerworks/cn/java/j-lo-WebSocket/

     ?  http://www.tuicool.com/articles/7zyMvy6

        http://www.alixixi.com/web/a/2014032492868.shtml

轉載于:https://www.cnblogs.com/vincent-vg/p/5831421.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/254541.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/254541.shtml
英文地址,請注明出處:http://en.pswp.cn/news/254541.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

多線程和多進程的區別(小結)

分類&#xff1a; linux 2009-06-19 09:33 11501人閱讀 評論(15) 收藏 舉報 很想寫點關于多進程和多線程的東西&#xff0c;我確實很愛他們。但是每每想動手寫點關于他們的東西&#xff0c;卻總是求全心理作祟&#xff0c;始終動不了手。 今天終于下了決心&#xff0c;寫點東西…

redis-cli使用密碼登錄

redis-cli使用密碼登錄 注意IP地址要寫正確&#xff01; 學習了: https://blog.csdn.net/lsm135/article/details/52932896 https://blog.csdn.net/zyz511919766/article/details/42268219 https://zhidao.baidu.com/question/756651357338691604.html 登錄后 auth pass 或者 r…

FFT快速傅式變換算法halcon算子,持續更新

目錄convol_fftconvol_gaborcorrelation_fftdeserialize_fft_optimization_dataenergy_gaborfft_genericfft_imagefft_image_invgen_bandfiltergen_bandpassgen_derivative_filtergen_filter_maskgen_gaborgen_gauss_filtergen_highpassgen_lowpassgen_mean_filtergen_sin_band…

仿照vue實現簡易的MVVM框架(一)

代碼github地址&#xff1a; https://github.com/susantong/myMVVM 主要的方法有&#xff1a; compile 深度遍歷前端界面的節點&#xff0c;將其復制進一個addQuene隊列中pasers 遍歷所有的節點&#xff0c;并將節點包裝成一個含有本節點、自定義屬性及屬性值的對象。要想實現雙…

tomcat 啟動時內存溢出

在tomcat_home/bin目錄下找到catalina.bat&#xff0c;用文本編輯器打開&#xff0c;加上下面一行&#xff1a; set JAVA_OPTS -Xms1024M -Xmx1024M -XX:PermSize256M -XX:MaxNewSize256M -XX:MaxPermSize256M 解釋一下各個參數&#xff1a; -Xms1024M&#xff1a;初始化堆內存…

@angular/platform-browser-dynamic

/** experimental */ export declare class JitCompilerFactory implements CompilerFactory {createCompiler(options?: CompilerOptions[]): Compiler; }export declare const platformBrowserDynamic: (extraProviders?: StaticProvider[] | undefined) > PlatformRef;…

牛人項目失敗的總結

tom_lt: 遇到的失敗項目比較多&#xff01;讓人郁悶&#xff01;&#xff01; 仔細分析原因&#xff0c;主要在于&#xff1a; 1.項目開始需求不明確。領導決定動手&#xff0c;就開始啟動項目&#xff0c;造成和客戶需要差距太大&#xff0c;導致失敗&#xff1b; 2.需求變更沒…

Android:日常學習筆記(8)———探究UI開發(5)

Android:日常學習筆記(8)———探究UI開發(5) ListView控件的使用 ListView概述 A view that shows items in a vertically scrolling list. The items come from the ListAdapter associated with this view. 1.關于ArrayAdapter&#xff1a; ArrayAdapter<T> 是 ListAd…

Geometric-Transformations圖像幾何變換halcon算子,持續更新

目錄affine_trans_imageaffine_trans_image_sizeconvert_map_typemap_imagemirror_imagepolar_trans_image_extpolar_trans_image_invprojective_trans_imageprojective_trans_image_sizerotate_imagezoom_image_factorzoom_image_sizeaffine_trans_image 功能&#xff1a;把任…

hibernate inverse屬性的作用

hibernate配置文件中有這么一個屬性inverse&#xff0c;它是用來指定關聯的控制方的。inverse屬性默認是false&#xff0c;若為false&#xff0c;則關聯由自己控制&#xff0c;若為true&#xff0c;則關聯由對方控制。見例子&#xff1a; 一個Parent有多個Child,一個Child只能有…

分布式鎖與實現(一)——基于Redis實現

概述 目前幾乎很多大型網站及應用都是分布式部署的&#xff0c;分布式場景中的數據一致性問題一直是一個比較重要的話題。分布式的CAP理論告訴我們“任何一個分布式系統都無法同時滿足一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;和…

淺析軟件項目管理中十個誤區(來自:http://manager.csdn.net/n/20051213/30907.html)

隨著計算機硬件水平的不斷提高&#xff0c;計算機軟件的規模和復雜度也隨之增加。計算機軟件開發從“個人英雄”時代向團隊時代邁進&#xff0c;計算機軟件項目的管理也從“作坊式”管理向“軟件工廠式”管理邁進。這就要求軟件開發人員特別是軟件項目管理人員更深一步地理解和…

倆孩隨筆

倆孩隨筆 有人給我貼了技術男加奶爸的標簽&#xff0c;不過這兩項都不是我的強項。我深知自己最大的長處在哪&#xff1a;普通&#xff0c;扔人堆里&#xff0c;不是認不出來&#xff0c;而是壓根看不著。想把事情做好&#xff0c;常常會用力過度。工作平平淡淡&#xff0c;需…

Inpainting圖像修復halcon算子,持續更新

目錄harmonic_interpolationinpainting_anisoinpainting_cedinpainting_ctinpainting_mcfinpainting_textureharmonic_interpolation 功能&#xff1a;對一個圖像區域執行諧波插值。 inpainting_aniso 功能&#xff1a;通過各向異性擴散執行圖像修復。 inpainting_ced 功能…

算法(偽代碼)的書寫

q ? Queue&#xff08;隊列&#xff09;, s ? Set&#xff08;集合&#xff09;pq ? PriorityQueue&#xff08;優先隊列&#xff09;d ? distance1. initialization 變量&#xff0c;數據結構的定義&#xff0c;及初始值的賦值&#xff1b;比如著名的 Dijkstra &#xff0…

第八次作業——系統設計與團隊分配(個人)

團隊作業地址&#xff1a;https://www.cnblogs.com/clio-hhhhhhl/p/9079157.html 個人碼云地址&#xff1a;https://gitee.com/Cliohl/events 團隊碼云地址&#xff1a;https://gitee.com/Cliohl/zhuoyue 項目進展&#xff1a; 上禮拜進展&#xff1a;把部分前端頁面實現出來&a…

深入理解Activity啟動流程(二)–Activity啟動相關類的類圖

本文原創作者:Cloud Chou. 歡迎轉載&#xff0c;請注明出處和本文鏈接 本系列博客將詳細闡述Activity的啟動流程&#xff0c;這些博客基于Cm 10.1源碼研究。 在介紹Activity的詳細啟動流程之前&#xff0c;先為大家介紹Activity啟動時涉及到的類&#xff0c;這樣大家可以有大概…

Lines色線halcon算子,持續更新

目錄bandpass_imagelines_colorlines_facetlines_gaussbandpass_image 功能&#xff1a;使用帶通濾波器提取邊緣。 lines_color 功能&#xff1a;檢測色線和它們的寬度。 lines_facet 功能&#xff1a;使用面模型檢測線。 lines_gauss 功能&#xff1a;檢測線和它們的寬…

疑問+軟件

問題 1學好軟件工程需要打好哪些基礎&#xff1f; 2怎樣學好軟件工程&#xff1f; 3軟件工程的發展前景如何&#xff1f; 4軟件工程具體能從事哪些職業&#xff1f; 5怎樣準確的找到自己的定位&#xff1f; 軟件 1支付寶 優點&#xff1a;支付便捷&#xff0c;轉賬方便&#xf…

成功的項目管理

內容提要 第一講 項目與項目管理 1.項目的基本概念 2.項目管理的概念 3.項目管理的重要性 第二講 項目管理的最新發展 1.現代項目管理的創立過程 2.現代項目管理的發展趨勢 3.項目管理流行的原因 第三講 信息時代的項目管理 1.信息時代的特點 2.信息時代項目管理的特點 3.按項目…