亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Java后端WebSocket的Tomcat實現

2019-11-15 01:15:51
字體:
來源:轉載
供稿:網友
java后端WebSocket的Tomcat實現

隨著互聯網的發展,傳統的HTTP協議已經很難滿足Web應用日益復雜的需求了。近年來,隨著HTML5的誕生,WebSocket協議被提出,它實現了瀏覽器與服務器的全雙工通信,擴展了瀏覽器與服務端的通信功能,使服務端也能主動向客戶端發送數據。

我們知道,傳統的HTTP協議是無狀態的,每次請求(request)都要由客戶端(如瀏覽器)主動發起,服務端進行處理后返回response結果,而服務端很難主動向客戶端發送數據;這種客戶端是主動方,服務端是被動方的傳統Web模式對于信息變化不頻繁的Web應用來說造成的麻煩較小,而對于涉及實時信息的Web應用卻帶來了很大的不便,如帶有即時通信、實時數據、訂閱推送等功能的應用。在WebSocket規范提出之前,開發人員若要實現這些實時性較強的功能,經常會使用折衷的解決方法:輪詢(polling)和Comet技術。其實后者本質上也是一種輪詢,只不過有所改進。

輪詢是最原始的實現實時Web應用的解決方案。輪詢技術要求客戶端以設定的時間間隔周期性地向服務端發送請求,頻繁地查詢是否有新的數據改動。明顯地,這種方法會導致過多不必要的請求,浪費流量和服務器資源。

Comet技術又可以分為長輪詢和流技術。長輪詢改進了上述的輪詢技術,減小了無用的請求。它會為某些數據設定過期時間,當數據過期后才會向服務端發送請求;這種機制適合數據的改動不是特別頻繁的情況。流技術通常是指客戶端使用一個隱藏的窗口與服務端建立一個HTTP長連接,服務端會不斷更新連接狀態以保持HTTP長連接存活;這樣的話,服務端就可以通過這條長連接主動將數據發送給客戶端;流技術在大并發環境下,可能會考驗到服務端的性能。

這兩種技術都是基于請求-應答模式,都不算是真正意義上的實時技術;它們的每一次請求、應答,都浪費了一定流量在相同的頭部信息上,并且開發復雜度也較大。

伴隨著HTML5推出的WebSocket,真正實現了Web的實時通信,使B/S模式具備了C/S模式的實時通信能力。WebSocket的工作流程是這樣的:瀏覽器通過JavaScript向服務端發出建立WebSocket連接的請求,在WebSocket連接建立成功后,客戶端和服務端就可以通過TCP連接傳輸數據。因為WebSocket連接本質上是TCP連接,不需要每次傳輸都帶上重復的頭部數據,所以它的數據傳輸量比輪詢和Comet技術小了很多。本文不詳細地介紹WebSocket規范,主要介紹下WebSocket在Java Web中的實現。

JavaEE 7中出了JSR-356:Java API for WebSocket規范。不少Web容器,如Tomcat,Nginx,Jetty等都支持WebSocket。Tomcat從7.0.27開始支持WebSocket,從7.0.47開始支持JSR-356,下面的Demo代碼也是需要部署在Tomcat7.0.47上才能運行。

對瀏覽器的支持情況:

新建一個dynamic web項目:

客戶端(Web主頁)代碼:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%><%Stringpath=request.getContextPath();StringbasePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPEHTML><html><head><basehref="<%=basePath%>"><title>MyWebSocket</title></head><body>Welcome<br/><inputid="text"type="text"/><buttononclick="send()">Send</button><buttononclick="closeWebSocket()">Close</button><divid="message"></div></body><scripttype="text/Javascript">varwebsocket=null;//判斷當前瀏覽器是否支持WebSocketif('WebSocket'inwindow){websocket=newWebSocket("ws://localhost:8080/MyWebSocket/websocket");}else{alert('Notsupportwebsocket')}//連接發生錯誤的回調方法websocket.onerror=function(){setMessageInnerHTML("error");};//連接成功建立的回調方法websocket.onopen=function(event){setMessageInnerHTML("open");}//接收到消息的回調方法websocket.onmessage=function(){setMessageInnerHTML(event.data);}//連接關閉的回調方法websocket.onclose=function(){setMessageInnerHTML("close");}//監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket連接,防止連接還沒斷開就關閉窗口,server端會拋異常。window.onbeforeunload=function(){websocket.close();}//將消息顯示在網頁上functionsetMessageInnerHTML(innerHTML){document.getElementById('message').innerHTML+=innerHTML+'<br/>';}//關閉連接functioncloseWebSocket(){websocket.close();}//發送消息functionsend(){varmessage=document.getElementById('text').value;websocket.send(message);}</script></html>

Java Web后端代碼

創建一個注解為:@ServerEndpoint的webscoket的服務端.供前臺訪問.因為想實現點其它功能.所以在廣播給所有人這個方法里邊加上了type以備區分

注解說明圖:

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798packagecom.chen.websocket;importjava.io.IOException;importjava.util.concurrent.CopyOnWriteArraySet;importjavax.websocket.OnClose;importjavax.websocket.OnError;importjavax.websocket.OnMessage;importjavax.websocket.OnOpen;importjavax.websocket.session;importjavax.websocket.server.ServerEndpoint;//該注解用來指定一個URI,客戶端可以通過這個URI來連接到WebSocket。類似Servlet的注解mapping。無需在web.xml中配置。@ServerEndpoint("/websocket")publicclassMyWebSocket{//靜態變量,用來記錄當前在線連接數。應該把它設計成線程安全的。PRivatestaticintonlineCount=0;//concurrent包的線程安全Set,用來存放每個客戶端對應的MyWebSocket對象。若要實現服務端與單一客戶端通信的話,可以使用Map來存放,其中Key可以為用戶標識privatestaticCopyOnWriteArraySet<MyWebSocket>webSocketSet=newCopyOnWriteArraySet<MyWebSocket>();//與某個客戶端的連接會話,需要通過它來給客戶端發送數據privateSessionsession;/***連接建立成功調用的方法*@paramsession可選的參數。session為與某個客戶端的連接會話,需要通過它來給客戶端發送數據*/@OnOpenpublicvoidonOpen(Sessionsession){this.session=session;webSocketSet.add(this);//加入set中addOnlineCount();//在線數加1System.out.println("有新連接加入!當前在線人數為"+getOnlineCount());}/***連接關閉調用的方法*/@OnClosepublicvoidonClose(){webSocketSet.remove(this);//從set中刪除subOnlineCount();//在線數減1System.out.println("有一連接關閉!當前在線人數為"+getOnlineCount());}/***收到客戶端消息后調用的方法*@parammessage客戶端發送過來的消息*@paramsession可選的參數*/@OnMessagepublicvoidonMessage(Stringmessage,Sessionsession){System.out.println("來自客戶端的消息:"+message);//群發消息for(MyWebSocketitem:webSocketSet){try{item.sendMessage(message);}catch(IOExceptione){e.printStackTrace();continue;}}}/***發生錯誤時調用*@paramsession*@paramerror*/@OnErrorpublicvoidonError(Sessionsession,Throwableerror){System.out.println("發生錯誤");error.printStackTrace();}/***這個方法與上面幾個方法不一樣。沒有用注解,是根據自己需要添加的方法。*@parammessage*@throwsIOException*/publicvoidsendMessage(Stringmessage)throwsIOException{this.session.getBasicRemote().sendText(message);//this.session.getAsyncRemote().sendText(message);}publicstaticsynchronizedintgetOnlineCount(){returnonlineCount;}publicstaticsynchronizedvoidaddOnlineCount(){MyWebSocket.onlineCount++;}publicstaticsynchronizedvoidsubOnlineCount(){MyWebSocket.onlineCount--;}}

該Demo在以下環境測試過:

1.Jdk7+Tomcat7.0.47

2.Jdk7+Tomcat7.0.52

3.Jdk7+Tomcat8.0.3

4.Jdk7+Glassfish4

注意事項:在Eclipse或者MyEclipse中,需要添加Tomcat的library。直接拷貝Tomcat里lib目錄下的jar包有時會出錯。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲欧美国产一本综合首页| 午夜精品一区二区三区av| 狠狠躁夜夜躁人人爽天天天天97| 国产成人精品在线| 欧美激情免费观看| 亚洲国产成人精品女人久久久| 精品久久久久久中文字幕大豆网| 日韩在线观看免费高清完整版| 日本精品久久久| 亚洲精品按摩视频| 欧美日韩国产999| 亚洲黄色av网站| 国产精品欧美日韩一区二区| 欧洲成人在线观看| 亚洲精品视频中文字幕| 色妞欧美日韩在线| 亚洲国内精品在线| 精品综合久久久久久97| 国产精品久久久久福利| 久久久久久久影视| 亚洲欧美激情一区| 亚洲激情视频在线| 欧美性xxxx18| 性欧美xxxx交| 狠狠躁天天躁日日躁欧美| 国产福利精品视频| 国产精品露脸av在线| 亚洲天堂成人在线视频| 91精品国产91久久久久福利| 国产精品美女主播| 欧美丰满老妇厨房牲生活| 日韩美女av在线免费观看| 国产精品热视频| 久久精品视频中文字幕| 欧美裸体xxxx| 欧美日韩成人免费| 激情av一区二区| 一区二区三区精品99久久| www亚洲精品| 久久久国产一区二区| 成人字幕网zmw| 久久人人爽国产| 国产脚交av在线一区二区| 欧美成aaa人片在线观看蜜臀| 欧美黄色免费网站| 成人久久一区二区三区| 久久夜色撩人精品| 668精品在线视频| 俺去啦;欧美日韩| 亚洲午夜未满十八勿入免费观看全集| 亚洲2020天天堂在线观看| 亚洲精品欧美日韩专区| 亚洲国产古装精品网站| 91精品国产网站| 国产区亚洲区欧美区| 国产精品美女网站| 亚洲一区二区三区久久| 成人免费网站在线看| 日韩成人xxxx| 欧美高清视频在线| 美日韩在线视频| 日韩一区av在线| 日韩av最新在线| 欧美成人性色生活仑片| 亚洲精品国精品久久99热| 国产精品一二区| 欧美黄色小视频| 久久高清视频免费| 久久久精品国产一区二区| 亚洲国产精品va在线看黑人| 欧美色欧美亚洲高清在线视频| 成人xxxxx| 亚洲美女自拍视频| 亚洲一区精品电影| 亚洲午夜久久久影院| 亚洲第一二三四五区| 一区二区三区视频免费在线观看| 日韩欧美在线视频日韩欧美在线视频| 性欧美亚洲xxxx乳在线观看| 在线精品国产成人综合| 久久在线视频在线| 一区二区三区视频免费| 国产精品视频网| 欧美性精品220| 久久精品精品电影网| 欧美激情亚洲精品| 国产精品入口福利| 亚洲精品国偷自产在线99热| 国产一区二区三区在线播放免费观看| 中文字幕欧美日韩| 91久久精品国产91久久性色| 国产最新精品视频| 欧美成人免费观看| 国产精品自产拍在线观看中文| 日韩电影免费在线观看中文字幕| 911国产网站尤物在线观看| 91久久久亚洲精品| 亚洲欧美在线播放| 国产视频自拍一区| 色婷婷综合成人av| 欧美成人激情视频| 精品久久久久久久久久久久| 亚洲国产日韩欧美在线动漫| 久久久亚洲天堂| 国语自产偷拍精品视频偷| 日韩高清电影免费观看完整| 中文字幕少妇一区二区三区| 国产成人aa精品一区在线播放| 欧美成人四级hd版| 国产日韩欧美日韩| 一区二区欧美久久| 欧美大片免费观看在线观看网站推荐| 欧美视频专区一二在线观看| 一本大道亚洲视频| 91久久久亚洲精品| 成人a级免费视频| 亚洲亚裔videos黑人hd| 亚洲精品网站在线播放gif| 中文字幕亚洲专区| 中文字幕国产亚洲2019| 亚洲网站在线看| 这里只有精品久久| 欧美国产一区二区三区| 2021国产精品视频| 欧美大尺度在线观看| 国内精品美女av在线播放| 精品久久久精品| 在线中文字幕日韩| 亚洲a区在线视频| 久久国产精品视频| 久久精品小视频| 亚洲欧洲国产精品| 欧美一级视频在线观看| 亚洲第一综合天堂另类专| 最近的2019中文字幕免费一页| 亚洲天堂免费观看| 国产日韩综合一区二区性色av| 一区二区成人av| xvideos国产精品| 亚洲肉体裸体xxxx137| 欧美日韩一区二区精品| 国产精品自拍网| 狠狠色噜噜狠狠狠狠97| 岛国视频午夜一区免费在线观看| 国产日韩专区在线| 久久影视电视剧免费网站清宫辞电视| 欧美激情免费视频| 98精品在线视频| 国产精品网站视频| 亚洲美女在线视频| 国产亚洲激情在线| 精品少妇v888av| 在线亚洲午夜片av大片| 亚洲人成电影网站色…| 久久久精品中文字幕| 久久久国产一区| 日韩风俗一区 二区| 欧美午夜性色大片在线观看| 亚洲一区二区福利| 国产精品久久77777| 蜜月aⅴ免费一区二区三区| 97成人精品区在线播放| 欧美成人精品在线视频| 亚洲免费人成在线视频观看|