乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      【Java實(shí)戰(zhàn)干貨警告】談?wù)刉eb端實(shí)現(xiàn)即時(shí)消息推送五種方式

       一本正經(jīng)地胡鬧 2019-06-29

      引言:

      在互聯(lián)網(wǎng)高速發(fā)展的時(shí)代里,web應(yīng)用大有取代桌面應(yīng)用的趨勢,不必再去繁瑣的安裝各種軟件,只需一款主流瀏覽器即可完成大部分常規(guī)操作,這些原因都在吸引著軟件廠商和消費(fèi)者。而隨著各大廠商瀏覽器版本的迭代,前端技術(shù)的不斷革新,消息推送用到的場景也越來越多了。

      收發(fā)郵件提醒,在線IM聊天,自動化辦公提示等等,web系統(tǒng)里總是能見到消息推送的應(yīng)用。消息推送用好了能增強(qiáng)用戶體驗(yàn),用不好則會起相反的效果。在司空見慣的使用過程中,有沒有對其中的原理產(chǎn)生興趣呢?實(shí)現(xiàn)消息推送有N種解決方案,本文針對其中的幾種,進(jìn)行原理性的講解并附有簡單的代碼實(shí)現(xiàn)。

      目錄:

      一、什么是消息推送
      二、web端的消息推送
      三、實(shí)現(xiàn)個(gè)性化的推送
       

      一、什么是消息推送

       

      • 經(jīng)典場景1

      當(dāng)我在官網(wǎng)觀望猶豫時(shí),突然看到了上面消息,一位神秘的徐老板竟然爆出了麻痹戒指??!我的天,于是我果斷開始了游戲!這消息很及時(shí)!
       

      • 經(jīng)典場景2

      當(dāng)我拿起手機(jī)不知干嘛時(shí)收到了這條招女婿的消息.......瞬間來了精神

      上述兩種場景,是生活中很常見的場景,通過圖文描述,應(yīng)該已經(jīng)清楚了推送的場景,也引出了兩大推送種類,web端消息推送和移動端消息推送。接下來對消息推送進(jìn)行具體的解釋。

      概念:

      消息推送(Push)指運(yùn)營人員通過自己的產(chǎn)品或第三方工具對用戶當(dāng)前網(wǎng)頁或移動設(shè)備進(jìn)行的主動消息推送。用戶可以在網(wǎng)頁上或移動設(shè)備鎖定屏幕和通知欄看到push消息通知。以此來實(shí)現(xiàn)用戶的多層次需求,使得用戶能夠自己設(shè)定所需要的信息頻道,得到即時(shí)消息,簡單說就是一種定制信息的實(shí)現(xiàn)方式。我們平時(shí)瀏覽郵箱時(shí)突然彈出消息提示收到新郵件就屬于web端消息推送,在手機(jī)鎖屏上看到的微信消息等等都屬于APP消息推送。 

      二、web端的消息推送


      這一章節(jié)主要對幾種消息推送的方式進(jìn)行原理性的講解,并貼出簡單實(shí)現(xiàn)的代碼。

      主要介紹其中的五種實(shí)現(xiàn)方式:短輪詢、Comet、Flash XMLSocket、Server-sent、WebSocket。

      1、短輪詢

      指在特定的的時(shí)間間隔(如每10秒),由瀏覽器對服務(wù)器發(fā)出HTTP request,然后由服務(wù)器返回最新的數(shù)據(jù)給客戶端的瀏覽器。瀏覽器做處理后進(jìn)行顯示。無論后端此時(shí)是否有新的消息產(chǎn)生,都會進(jìn)行響應(yīng)。字面上看,這種方式是最簡單的。這種方式的優(yōu)點(diǎn)是,后端編寫非常簡單,邏輯不復(fù)雜。但是缺點(diǎn)是請求中大部分中是無用的,浪費(fèi)了帶寬和服務(wù)器資源??偨Y(jié)來說,簡單粗暴,適用于小型(偷懶)應(yīng)用。

      基于Jquery的ajax前端代碼:

      1. <body>
      2. <div id="push"></div>
      3. <script>
      4. $(function () {
      5. setInterval(function () {
      6. getMsg(function (res) {
      7. $("#push").append("<p>" + res +"</p>");
      8. })
      9. },10000);
      10. });
      11. function getMsg(handler){
      12. $.ajax({
      13. url:"/ShortPollingServlet",
      14. type:"post",
      15. success:function (res) {
      16. handler(res)
      17. }
      18. });
      19. }
      20. </script>
      21. </body>

      servlet簡單實(shí)現(xiàn)后端代碼:

      1. public class ShortPollingServlet extends HttpServlet {
      2. public static int count = 0;
      3. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      4. //模擬業(yè)務(wù)代碼
      5. count++;
      6. response.getWriter().print("msg:" + count );
      7. }
      8. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      9. doPost(request,response);
      10. }
      11. }

      2、Comet

      包括了長輪詢和長連接,長輪詢是客戶端向服務(wù)器發(fā)送Ajax請求,服務(wù)器接到請求后hold住連接,直到有新消息才返回響應(yīng)信息并關(guān)閉連接,客戶端處理完響應(yīng)信息后再向服務(wù)器發(fā)送新的請求;長連接是在頁面中的iframe發(fā)送請求到服務(wù)端,服務(wù)端hold住請求并不斷將需要返回前端的數(shù)據(jù)封裝成調(diào)用javascript函數(shù)的形式響應(yīng)到前端,前端不斷收到響應(yīng)并處理。Comet的實(shí)現(xiàn)原理和短輪詢相比,很明顯少了很多無用請求,減少了帶寬壓力,實(shí)現(xiàn)起來比短輪詢復(fù)雜一丟丟。比用短輪詢的同學(xué)有夢想時(shí),就可以用Comet來實(shí)現(xiàn)自己的推送。

      長輪詢的優(yōu)點(diǎn)很明顯,在無消息的情況下不會頻繁的請求,耗費(fèi)資小并且實(shí)現(xiàn)了服務(wù)端主動向前端推送的功能,但是服務(wù)器hold連接會消耗資源,返回?cái)?shù)據(jù)順序無保證,難于管理維護(hù)。WebQQ(好像掛了)就是這樣實(shí)現(xiàn)的。

      基于Jquery的ajax前端代碼:

      1. <body>
      2. <div id="push"></div>
      3. <script>
      4. $(function () {
      5. getMsg();
      6. });
      7. function getMsg() {
      8. $.ajax({
      9. url:"/LongPollingServlet",
      10. type:"post",
      11. success:function (res) {
      12. $("#push").append("<p>" + res +"</p>");
      13. getMsg();
      14. }
      15. });
      16. }
      17. </script>
      18. </body>

      servlet簡單實(shí)現(xiàn)后端代碼:

      1. public class LongPollingServlet extends HttpServlet {
      2. public static int count = 0;
      3. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      4. count++;
      5. //睡眠時(shí)間模擬業(yè)務(wù)操作等待時(shí)間
      6. double random = Math.round(Math.random()*10);
      7. long sleepTime = new Double(random).longValue();
      8. try{
      9. Thread.sleep(sleepTime*1000);
      10. response.getWriter().print("msg:" + count + " after " + sleepTime + "seconds servicing");
      11. }catch (Exception e){
      12. e.printStackTrace();
      13. }
      14. }
      15. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      16. doPost(request,response);
      17. }
      18. }

      長連接優(yōu)點(diǎn)是消息即是到達(dá),不發(fā)無用請求,管理起來也相對方便。缺點(diǎn)是服務(wù)端維護(hù)一個(gè)長連接會增加開銷。比如Gmail聊天(沒用過)就是這樣實(shí)現(xiàn)的。

      基于Jquery的ajax前端代碼:

      1. <head>
      2. <title>pushPage</title>
      3. <script type="text/javascript">
      4. function loadData(msg) {
      5. var newChild = document.createElement("p");
      6. newChild.innerHTML = msg;
      7. document.getElementById("push").appendChild(newChild);
      8. }
      9. </script>
      10. </head>
      11. <body>
      12. <div id="push"></div>
      13. <iframe src="/LongConnServlet" frameborder="0" name="longConn"></iframe>
      14. </body>

      servlet簡單實(shí)現(xiàn)后端代碼:

      1. public class LongConnServlet extends HttpServlet {
      2. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      3. boolean flag = true;
      4. int i = 0;
      5. while (flag){
      6. try {
      7. //模擬每1秒查詢一次數(shù)據(jù)庫,看是否有新的消息可以推送
      8. Thread.sleep(1*1000);
      9. }catch (Exception e){
      10. e.printStackTrace();
      11. }
      12. String pushMsg = "push msg : " + i;
      13. response.setContentType("text/html;charset=GBK");
      14. response.getWriter().write("<script type='text/javascript'>parent.loadData('" + pushMsg + "')</script>");
      15. response.flushBuffer();
      16. i++;
      17. if(i==5){
      18. flag = false;
      19. }
      20. }
      21. }
      22. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      23. doPost(request,response);
      24. }
      25. }

      3、Flash XMLSocket

      在 HTML 頁面中內(nèi)嵌入一個(gè)使用了 XMLSocket 類的 Flash 程序。JavaScript 通過調(diào)用此 Flash 程序提供的socket接口與服務(wù)器端的socket進(jìn)行通信。JavaScript 在收到服務(wù)器端以 XML 格式傳送的信息后可以很容易地控制 HTML 頁面的內(nèi)容顯示。

      原理示意圖
      利用Flash XML Socket實(shí)現(xiàn)”服務(wù)器推”技術(shù)前提:
      (1)Flash提供了XMLSocket類,服務(wù)器利用Socket向Flash發(fā)送數(shù)據(jù);
      (2)JavaScript和Flash的緊密結(jié)合JavaScript和Flash可以相互調(diào)用。
      優(yōu)點(diǎn)是實(shí)現(xiàn)了socket通信,不再利用無狀態(tài)的http進(jìn)行偽推送。但是缺點(diǎn)更明顯:
      1.客戶端必須安裝 Flash 播放器;
      2.因?yàn)?XMLSocket 沒有 HTTP 隧道功能,XMLSocket 類不能自動穿過防火墻;
      3.因?yàn)槭鞘褂锰捉涌?,需要設(shè)置一個(gè)通信端口,防火墻、代理服務(wù)器也可能對非 HTTP 通道端口進(jìn)行限制。
      這種方案在一些網(wǎng)絡(luò)聊天室,網(wǎng)絡(luò)互動游戲中已得到廣泛使用。不進(jìn)行代碼示例。

      4、Server-sent

      服務(wù)器推指的是HTML5規(guī)范中提供的服務(wù)端事件EventSource,瀏覽器在實(shí)現(xiàn)了該規(guī)范的前提下創(chuàng)建一個(gè)EventSource連接后,便可收到服務(wù)端的發(fā)送的消息,實(shí)現(xiàn)一個(gè)單向通信??蛻舳诉M(jìn)行監(jiān)聽,并對響應(yīng)的信息處理顯示。該種方式已經(jīng)實(shí)現(xiàn)了服務(wù)端主動推送至前端的功能。優(yōu)點(diǎn)是在單項(xiàng)傳輸數(shù)據(jù)的場景中完全滿足需求,開發(fā)人員擴(kuò)展起來基本不需要改后端代碼,直接用現(xiàn)有框架和技術(shù)就可以集成。

      基于HTML5的Server-sent事件:

      1. <head>
      2. <title>Title</title>
      3. <script>
      4. var source = new EventSource("/ServerSentServlet");//創(chuàng)建一個(gè)新的 EventSource對象,
      5. source.onmessage = function (evt) {//每接收到一次更新,就會發(fā)生 onmessage事件
      6. var newChild = document.createElement("p");
      7. newChild.innerHTML = evt.data;
      8. document.getElementById("push").appendChild(newChild);
      9. }
      10. </script>
      11. </head>
      12. <body>
      13. <div id="push"></div>
      14. </body>

      servlet簡單實(shí)現(xiàn)后端代碼:

      1. public class ServerSentServlet extends HttpServlet {
      2. public static int count = 0;
      3. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      4. count++;
      5. response.setCharacterEncoding("UTF-8");
      6. response.setHeader("Content-Type", "text/event-stream");//設(shè)置服務(wù)器端事件流
      7. response.setHeader("Cache-Control","no-cache");//規(guī)定不對頁面進(jìn)行緩存
      8. response.setHeader("Pragma","no-cache");
      9. response.setDateHeader("Expires",0);
      10. PrintWriter pw = response.getWriter();
      11. pw.println("retry: 5000"); //設(shè)置請求間隔時(shí)間
      12. pw.println("data: " + "msg:" + count +"\n\n");
      13. }
      14. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
      15. doPost(request,response);
      16. }
      17. }

      5、WebSocket

      WebSocket是HTML5下一種新的協(xié)議,是基于TCP的應(yīng)用層協(xié)議,只需要一次連接,便可以實(shí)現(xiàn)全雙工通信,客戶端和服務(wù)端可以相互主動發(fā)送消息。客戶端進(jìn)行監(jiān)聽,并對響應(yīng)的消息處理顯示。這個(gè)技術(shù)相信基本都聽說過,就算沒寫過代碼,也大概知道干嘛的。通過名字就能知道,這是一個(gè)Socket連接,一個(gè)能在瀏覽器上用的Socket連接。是HTML5標(biāo)準(zhǔn)中的一個(gè)內(nèi)容,瀏覽器通過javascript腳本手動創(chuàng)建一個(gè)TCP連接與服務(wù)端進(jìn)行通訊。優(yōu)點(diǎn)是雙向通信,都可以主動發(fā)送消息,既可以滿足“問”+“答”的響應(yīng)機(jī)制,也可以實(shí)現(xiàn)主動推送的功能。缺點(diǎn)就是編碼相對來說會多點(diǎn),服務(wù)端處理更復(fù)雜(我覺得當(dāng)一條有情懷的咸魚就應(yīng)該用這個(gè)?。?。

      前端代碼:

      1. <body>
      2. <div id="push"></div>
      3. </body>
      4. <script>
      5. $(function () {
      6. var webSocket = new WebSocket("ws://localhost:8080/ws");
      7. webSocket.onmessage = function (ev) {
      8. $("#push").append("<p>" + ev.data +"</p>");
      9. }
      10. })
      11. </script>

      基于注解簡單實(shí)現(xiàn)后端代碼:

      1. @ServerEndpoint("/ws")
      2. public class MyWebSocket {
      3. private Session session;
      4. public MyWebSocket() {
      5. }
      6. @OnOpen
      7. public void onOpen(Session session) {
      8. this.session = session;
      9. System.out.println("someone connect");
      10. int count = 1;
      11. while (count<=5){
      12. //睡眠時(shí)間模擬業(yè)務(wù)操作等待時(shí)間
      13. double random = Math.round(Math.random()*10);
      14. long sleepTime = new Double(random).longValue();
      15. try {
      16. Thread.sleep(sleepTime*1000);
      17. session.getBasicRemote().sendText("msg:" + count +" from server after" + sleepTime + " seconds");
      18. }catch (Exception e){
      19. e.printStackTrace();
      20. }
      21. count++;
      22. }
      23. }
      24. @OnError
      25. public void onError(Throwable t){
      26. System.out.println("something error");
      27. }
      28. }

      以上是對五種推送方式原理的簡單講解和代碼的實(shí)現(xiàn)。
       

      三、實(shí)現(xiàn)個(gè)性化的推送 

      上面說了很多原理,也給出了簡單的代碼實(shí)現(xiàn),但是在實(shí)際生產(chǎn)過程中,肯定不能用上面的代碼,針對自己系統(tǒng)的應(yīng)用場景選擇合適的推送方案才是合理的,因此最后簡單說一下實(shí)現(xiàn)個(gè)性化推送的兩種方式。第一種很簡單,直接使用第三方實(shí)現(xiàn)的推送,無需復(fù)雜的開發(fā)運(yùn)維,直接可以使用。第二種就是自己封裝,可以選擇如今較為火熱的WebSocket來實(shí)現(xiàn)系統(tǒng)的推送。

      1、第三方

       關(guān)于第三方推送平臺,GoEasy。

      推薦理由是GoEasy的理念符合我們的選擇

      (1)更簡單的方式將消息從服務(wù)器端推送至客戶端
      (2)更簡單的方式將消息從各種客戶端推送至客戶端

      GoEasy具體的使用方式這里不再贅述,詳見官網(wǎng)。對于后端后端開發(fā)者,可直接使用Rest方式調(diào)用推送,對于前端或web開發(fā)者,可以從web客戶端用javascript腳本進(jìn)行調(diào)用推送。

      2、封裝自己的推送服務(wù)(總結(jié)就是對于真的想開發(fā)的還是websocket吧!

      如果是一個(gè)老系統(tǒng)進(jìn)行擴(kuò)展,那么更推薦使用Server-sent,服務(wù)端改動量不會很大。如果是新系統(tǒng),更推薦websocket,實(shí)現(xiàn)的功能功能更全面。

      我們以websocket為例,不再貼出具體的代碼實(shí)現(xiàn)。

      我們?nèi)绻枰褂脀ebsocket技術(shù)實(shí)現(xiàn)自己的推送服務(wù),需要注意哪些點(diǎn),或者說需要踩哪些坑呢,列出幾點(diǎn)供大家參考:

      長連接的心跳處理;
      從WebSocket中獲取HttpSession進(jìn)行用戶相關(guān)操作;
      服務(wù)端調(diào)優(yōu)實(shí)現(xiàn)高并發(fā)量client同時(shí)在線;
      服務(wù)端維持多用戶的狀態(tài);
      群發(fā)消息;
      等等等….

      關(guān)于WebSocket開發(fā)關(guān)注下篇,謝謝

      轉(zhuǎn)自 https://blog.csdn.net/hj7jay/article/details/89761047

       

       

        本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多