Java Websocket实例【服务端与客户端实现全双工通讯】
Java Websocket實(shí)例【服務(wù)端與客戶端實(shí)現(xiàn)全雙工通訊】
現(xiàn)很多網(wǎng)站為了實(shí)現(xiàn)即時通訊,所用的技術(shù)都是輪詢(polling)。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務(wù)器發(fā)
出HTTP?request,然后由服務(wù)器返回最新的數(shù)據(jù)給客服端的瀏覽器。這種傳統(tǒng)的HTTP?request?的模式帶來很明顯的缺點(diǎn)?–?瀏
覽器需要不斷的向服務(wù)器發(fā)出請求,然而HTTP?request?的header是非常長的,里面包含的數(shù)據(jù)可能只是一個很小的值,這樣會占
用很多的帶寬。WebSocket提供了一個受歡迎的技術(shù),以替代我們過去幾年一直在用的Ajax技術(shù)。
一、什么是WebSocket?API?
WebSocket?API是下一代客戶端-服務(wù)器的異步通信方法。該通信取代了單個的TCP套接字,使用ws或wss協(xié)議,可用于任意的
客戶端和服務(wù)器程序。WebSocket目前由W3C進(jìn)行標(biāo)準(zhǔn)化。WebSocket已經(jīng)受到Firefox?4、Chrome?4、Opera?10.70以及Safari?5等
瀏覽器的支持。
WebSocket?API最偉大之處在于服務(wù)器和客戶端可以在給定的時間范圍內(nèi)的任意時刻,相互推送信息。WebSocket并不限于以
Ajax(或XHR)方式通信,因?yàn)?/span>Ajax技術(shù)需要客戶端發(fā)起請求,而WebSocket服務(wù)器和客戶端可以彼此相互推送信息;XHR受到域
的限制,而WebSocket允許跨域通信。
Ajax技術(shù)很聰明的一點(diǎn)是沒有設(shè)計(jì)要使用的方式。WebSocket為指定目標(biāo)創(chuàng)建,用于雙向推送消息。
那么我就開始我在項(xiàng)目中對websocket的使用,首先使用的是J2EE7的架包。
?
架包加完之后,只需要再添加2個類就可以實(shí)現(xiàn)使用的功能了。
首先添加一個Java類,WebsocketController.java
[java]?view plaincopy
- package?com.lwl.activemq.controller.websocket;??
- ??
- import?java.util.Map;??
- import?java.util.concurrent.ConcurrentHashMap;??
- ??
- import?javax.websocket.*;??
- import?javax.websocket.server.PathParam;??
- import?javax.websocket.server.ServerEndpoint;??
- ??
- ??
- import?org.slf4j.Logger;??
- import?org.slf4j.LoggerFactory;??
- /**?
- ?*?功能說明:websocket處理類,?使用J2EE7的標(biāo)準(zhǔn)?
- ?*?@author?Administrator?
- ?*?@create?2016-8-11?下午4:08:35?
- ?*?@version?1.0?
- ?*/??
- @ServerEndpoint("/websocket/{myWebsocket}")??
- public?class?WebsocketController?{??
- ????private?static?final?Logger?logger?=?LoggerFactory.getLogger(WebsocketController.class);??
- ??
- ????public?static?Map<String,?Session>?clients?=?new?ConcurrentHashMap<String,?Session>();??
- ??
- ????/**?
- ?????*?打開連接時觸發(fā)?
- ?????*?@param?myWebsocket?
- ?????*?@param?session?
- ?????*/??
- ????@OnOpen??
- ????public?void?onOpen(@PathParam("myWebsocket")?String?myWebsocket,?Session?session){??
- ????????logger.info("Websocket?Start?Connecting:"?+?myWebsocket);??
- ????????System.out.println("進(jìn)入:"+myWebsocket);??
- ????????clients.put(myWebsocket,?session);??
- ????}??
- ??
- ????/**?
- ?????*?收到客戶端消息時觸發(fā)?
- ?????*?@param?myWebsocket?
- ?????*?@param?message?
- ?????*?@return?
- ?????*/??
- ????@OnMessage??
- ????public?String?onMessage(@PathParam("myWebsocket")?String?myWebsocket,?String?message)?{??
- ????????return?"Got?your?message?("+?message?+").Thanks?!";??
- ????}??
- ??
- ????/**?
- ?????*?異常時觸發(fā)?
- ?????*?@param?myWebsocket?
- ?????*?@param?throwable?
- ?????*/??
- ????@OnError??
- ????public?void?onError(@PathParam("myWebsocket")?String?myWebsocket,?Throwable?throwable)?{??
- ????????logger.info("Websocket?Connection?Exception:"?+?myWebsocket);??
- ????????logger.info(throwable.getMessage(),?throwable);??
- ????????clients.remove(myWebsocket);??
- ????}??
- ??
- ????/**?
- ?????*?關(guān)閉連接時觸發(fā)?
- ?????*?@param?myWebsocket?
- ?????*/??
- ????@OnClose??
- ????public?void?onClose(@PathParam("myWebsocket")?String?myWebsocket)?{??
- ????????logger.info("Websocket?Close?Connection:"?+?myWebsocket);??
- ????????clients.remove(myWebsocket);??
- ????}??
- ??
- ??
- ????/**?
- ?????*?將數(shù)據(jù)傳回客戶端?
- ?????*?異步的方式?
- ?????*?@param?myWebsocket?
- ?????*?@param?message?
- ?????*/??
- ????public?static?void?broadcast(String?myWebsocket,?String?message)?{??
- ????????if?(clients.containsKey(myWebsocket))?{??
- ????????????clients.get(myWebsocket).getAsyncRemote().sendText(message);??
- ????????}?else?{??
- ????????????throw?new?NullPointerException("["?+?myWebsocket?+"]Connection?does?not?exist");??
- ????????}??
- ????}??
- ??
- }??
然后添加相應(yīng)的接受頁面index.html:
[html]?view plaincopy
- <!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN"?"http://www.w3.org/TR/html4/loose.dtd">??
- <html>??
- ????<head>??
- ????????<meta?http-equiv="Content-Type"?content="text/html;?charset=UTF-8">??
- ????????<meta?http-equiv="X-UA-Compatible"?content="IE=edge">??
- ????????<meta?name="viewport"?content="width=device-width,?initial-scale=1">??
- ??????????<script?type="text/javascript"?src="resources/jquery-1.8.3.min.js"></script>??
- ?????</head>?????
- <body>??
- ??
- ???
- <script?type="text/javascript">??
- ?//測試controller是否可以進(jìn)入??
- //?ajaxDo("/activemq-client/index",null);??
- ???
- //?function?ajaxDo(url,data){??
- //???$.ajax({??
- //??????????url:url?,??
- //??????????type:?"post",??
- //??????????dataType:?"json",??
- //??????????data:?data,??
- //??????????success:function(result){??
- //?????????????if(result.success){??
- //?????????????????alert(result.data);??
- //?????????????}else{??
- //?????????????????alert(result.msg);??
- //?????????????}??
- //??????????}??
- //??????});??
- //?}??????
- ??
- ??
- //---------------------------------?webSocket?----------------------------------------------??
- ??initSocket("user");??
- ??initSocket("news");??
- ??initSocket("client");??
- ????
- ??
- function?initSocket(myWebsocket)?{??
- ??????
- ????var?webSocket?=?null;??
- ??????
- ????window.onbeforeunload?=?function?()?{??
- ????????//離開頁面時的其他操作??
- ????};??
- ??
- ????if?(!window.WebSocket)?{??
- ????????console("您的瀏覽器不支持websocket!");??
- ????????return?false;??
- ????}??
- ??
- ????var?target?=?'ws://'?+?window.location.host?+?"/activemq-client/websocket/"+myWebsocket;????
- ????????????
- ????????if?('WebSocket'?in?window)?{????
- ????????????webSocket?=?new?WebSocket(target);????
- ????????}?else?if?('MozWebSocket'?in?window)?{????
- ????????????webSocket?=?new?MozWebSocket(target);????
- ????????}?else?{????
- ????????????alert('WebSocket?is?not?supported?by?this?browser.');????
- ????????????return;????
- ????????}????
- ??????
- ??????
- ????//?收到服務(wù)端消息??
- ????webSocket.onmessage?=?function?(msg)?{??
- ????????????alert(msg.data);??
- ????????//?關(guān)閉連接??
- ????????webSocket.onclose();??
- ????????console.log(msg);??
- ????};??
- ??
- ????//?異常??
- ????webSocket.onerror?=?function?(event)?{??
- ????????console.log(event);??
- ????};??
- ??
- ????//?建立連接??
- ????webSocket.onopen?=?function?(event)?{??
- ????????console.log(event);??
- ????};??
- ??
- ????//?斷線??
- ????webSocket.onclose?=?function?()?{??
- ??????????
- ????????console.log("websocket斷開連接");??
- ????};??
- }??
- ??
- ??
- </script>??
- ??
- </body>??
- </html>??
好了,websocket已經(jīng)實(shí)現(xiàn)了,現(xiàn)在最重要的是我們要在哪兒監(jiān)聽哪些變動,在推送給前端的問題了,這里我監(jiān)聽了MQ消息隊(duì)
列中的某個Queen,如果獲取到消息就推送給前端展示,稍后我會把MQ的消息隊(duì)列也寫給大家看,做個參考。(當(dāng)然你也可以
監(jiān)聽屬于你自己的對象,主要是調(diào)用?WebsocketController.broadcast("client", jsonStr);第一個參數(shù)和前端的參數(shù)一
致,第二個參數(shù)是你想推送給前端的內(nèi)容)。
[java]?view plaincopy
- <span?style="font-size:14px;"><span?style="font-family:宋體;">package?com.lwl.activemq.listener;??
- ??
- import?javax.jms.JMSException;??
- import?javax.jms.Message;??
- import?javax.jms.MessageListener;??
- import?javax.jms.TextMessage;??
- ??
- import?org.apache.log4j.Logger;??
- import?org.springframework.stereotype.Component;??
- ??
- import?com.alibaba.fastjson.JSON;??
- import?com.lwl.activemq.domain.Client;??
- import?com.lwl.activemq.controller.websocket.WebsocketController;??
- ??
- @Component("clientPushListener")??
- public?class?ClientPushListener?implements?MessageListener?{??
- ?????protected?static?final?Logger?logger?=?Logger.getLogger(ClientPushListener.class);??
- ????@Override??
- ????public?void?onMessage(Message?message)?{??
- ?????????logger.info("[ClientPushListener.onMessage]:begin?onMessage.");??
- ????????????TextMessage?textMessage?=?(TextMessage)?message;??
- ????????????try?{??
- ????????????????String?jsonStr?=?textMessage.getText();??
- ????????????????logger.info("[ClientPushListener.onMessage]:receive?message?is,"+?jsonStr);??
- ????????????????if?(jsonStr?!=?null)?{??
- ????????????????????Client?info?=?JSON.parseObject(jsonStr,?Client.class);??
- ????????????????????System.out.println("==============================接受到的客戶信息?開始====================================");??
- ????????????????????System.out.println(info.toString());??
- ????????????????????System.out.println("==============================接受到的客戶信息?結(jié)束====================================");??
- ????????????????????WebsocketController.broadcast("client",?jsonStr);??
- ????????????????}??
- ????????????}?catch?(JMSException?e)?{??
- ????????????????logger.error("[ClientPushListener.onMessage]:receive?message?occured?an?exception",e);??
- ????????????}??
- ????????????logger.info("[ClientPushListener.onMessage]:end?onMessage.");??
- ????????}??
- }</span></span>??
總結(jié)
以上是生活随笔為你收集整理的Java Websocket实例【服务端与客户端实现全双工通讯】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028年中国团购行业投资分析
- 下一篇: 减肥个性签名短语