在咱們不少的Web應用中會遇到須要從後端將指定的數據或消息實時推送到前端,一般的作法是前端寫個腳本定時到後端獲取,或者藉助WebSocket技術實現先後端實時通信。因定時刷新的方法弊端不少(已再也不採用),因此基於WebSocket技術實現的通信方案正愈來愈受你們喜好,因而在ASP.NET中就有了鼎鼎大名的Signalr。但Signalr不是我們這裏的主角,這裏將給你們介紹另外一套基於WebSocket的先後端通信方案,能夠給你們在應用中多一個選擇。css
準備html
在開始動手前,我們先簡單介紹下方案的組成部分,以下:前端
RabbitMQ:是一個成熟的MQ隊列服務,由 Erlang 語言開發的 AMQP 的開源實現。這裏用來接收後端的指令並廣播到前端(基於topic模式)。關於更多RabbitMQ的實現能夠查看我另外一篇文章,傳送門jquery
RabbitMQ插件stomp:是一個讓RabbitMQ支持stomp協議的插件,必需安裝後才能經過RabbitMQ實現前端通信。安裝說明在此:http://www.rabbitmq.com/stomp.htmlgit
stomp.js:是一個基於stomp協議的客戶端實現,底層基於WebSocket通信協議。這裏用於前端實現WebSocket通信。官網地址:https://github.com/jmesnil/stomp-websocketgithub
Lezhima.Rest:是一個基於ASP.NET Core2的Web Api後端程序,用來模擬向前端發送指令。web
Lezhima.Site:是一個純前端技術的前端程序,用來模擬前端實時接收後臺的指令。後端
實現websocket
如上面所述,咱們已經清楚了整個實現思路,那麼下面就來看看具體的代碼實現吧。app
一、首先來看看Lezhima.Rest的MQ生產者代碼,以下:
1 /// <summary> 2 /// MQ生產者,採用topic模式推送指定內容 3 /// </summary> 4 /// <param name="objText"></param> 5 public static void PushMessage(string objText) 6 { 7 //建立MQ鏈接工廠 8 var factory = new ConnectionFactory() 9 { 10 HostName = "localhost", 11 Port = 5672, 12 UserName = "fans", 13 Password = "123456" 14 }; 15 //建立MQ鏈接 16 using (var connection = factory.CreateConnection()) 17 using (var channel = connection.CreateModel()) 18 { 19 //綁定交換器 20 channel.ExchangeDeclare(exchange: "topic/test", type: "topic"); 21 var body = Encoding.UTF8.GetBytes(objText); 22 //對指定routingkey發送內容 23 channel.BasicPublish(exchange: "amq.topic", 24 routingKey: "test", 25 basicProperties: null, 26 body: body); 27 } 28 }
二、Lezhima.Site的前端代碼,以下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <link href="main.css" rel="stylesheet" type="text/css" /> 6 <script src="Script/jquery.js"></script> 7 <script src="stomp.js"></script> 8 <style> 9 10 .box { 11 width: 440px; 12 float: left; 13 margin: 0 20px 0 20px; 14 } 15 .box div, .box input { 16 border: 1px solid; 17 -moz-border-radius: 4px; 18 border-radius: 4px; 19 width: 100%; 20 padding: 5px; 21 margin: 3px 0 10px 0; 22 } 23 24 .box div { 25 border-color: grey; 26 height: 300px; 27 overflow: auto; 28 } 29 30 div code { 31 display: block; 32 } 33 34 #first div code { 35 -moz-border-radius: 2px; 36 border-radius: 2px; 37 border: 1px solid #eee; 38 margin-bottom: 5px; 39 } 40 </style> 41 </head> 42 <body lang="en"> 43 <div id="first" class="box"> 44 <h2>接收來自後端的消息</h2> 45 <div></div> 46 </div> 47 <script> 48 var has_had_focus = false; 49 //封裝個接收呈現方法 50 var pipe = function (el_name) { 51 var div = $(el_name + ' div'); 52 var print = function (m) { 53 div.append($("<code>").text('後端的指令:'+ m)); 54 div.scrollTop(div.scrollTop() + 10000); 55 }; 56 return print; 57 }; 58 59 //RabbitMQ的服務地址 60 var mqUrl = "ws://localhost:15674/ws"; 61 //聲明個Stompjs客戶端 62 var client = Stomp.client(mqUrl); 63 64 var print_first = pipe('#first', function (data) { 65 client.send('/topic/test', { "content-type": "text/plain" }, data); 66 }); 67 68 //監聽鏈接事件 69 var on_connect = function (x) { 70 id = client.subscribe("/topic/test", function (d) { 71 print_first(d.body); 72 }); 73 }; 74 var on_error = function () { 75 console.log('error'); 76 }; 77 //鏈接MQ 78 client.connect('fans', '123456', on_connect, on_error, '/'); 79 80 </script> 81 </body> 82 </html> 83
三、分別運行「Lezhima.Rest」與「Lezhima.Site」程序後,效果是這個樣子的,以下:
總結
一、藉助RabbitMQ實現先後端通信功能時,必需先安裝RabbitMQ插件stomp,經過該插件可以使RabbitMQ支持WebSocket通信能力。而咱們的後端開發人員只需經過「生產者」方法按需向MQ發送數據便可,MQ將根據routingKey廣播給全部客戶端(消費者)。
二、前端藉助stomp.js能夠簡便的實現與RabbitMQ通信,並綁定相應的routingKey後承擔MQ消費者的能力,以達到先後端即時推送的效果。
聲明
本文爲做者原創,轉載請備註出處與保留原文地址,謝謝。如文章能給您帶來幫助,請點下推薦或關注,感謝您的支持!