RxJS入門(8)----建立一個完整的web application

來源:互聯網
上載者:User

標籤:

上接(7)

Getting Real-Time Updates from Twitter
  • 我們計劃的的第二部分是做一個即時的儀錶給地震,添加從Twitter相關的地球上正在發生的不同地震報告和資訊。為了實現這個,我們需要建立一個小的Node.js程式,它擷取tweets相關的地震的流。
  • Setting Up Our Node.js Environment
  • 配置我們的Node.js程式。包括RxJS,我們將會使用兩個比較重要的第三方modules使我們的編程會更容易:ws和twit。其他任何相似的modules應該對代碼的改動最小。
  • 首先,為我們的程式建立一個目錄,並install那些modules(我們將要使用的)。(注意npm命令的輸出,依賴目前的版本和包)
  • Client–Server Communication
  • 現在我們已經準備開搭建我們的程式了。讓我們建立一個名叫index.js的新檔案,在它裡面, tweet_stream這個檔案夾就是用來載入我們將用使用的modules:
var WebSocketServer = require(‘ws‘).Server;var Twit = require(‘twit‘);var Rx = require(‘rx‘);
var T = new Twit({consumer_key: ‘rFhfB5hFlth0BHC7iqQkEtTyw‘,consumer_secret: ‘zcrXEM1jiOdKyiFFlGYFAOo43Hsz383i0cdHYYWqBXTBoVAr1x‘,access_token: ‘14343133-nlxZbtLuTEwgAlaLsmfrr3D4QAoiV2fa6xXUVEwW9‘,access_token_secret: ‘57Dr99wECljyyQ9tViJWz0H3obNG3V4cr5Lix9sQBXju1‘});
  • 現在我們可以建立一個函數,onConnect,它將會做所有的搜素tweets和與client互動的工作。我們可以調用onConnect初始化一個WebSocket server一旦這個WebSocket串連和準備好了:
function onConnect(ws) {console.log(‘Client connected on localhost:8080‘);}var Server = new WebSocketServer({ port: 8080 });Rx.Observable.fromEvent(Server, ‘connection‘).subscribe(onConnect);
  • 我們可以登入我們的應用程式了,以WebSocket的8080連接埠開始:
  • 這個關於client串連的訊息不會被列印,是因為我們讓任何的瀏覽器串連到這個伺服器上。讓我們調整我們的儀錶代碼,我們將會使用RxJS-DOM的fromWebSocket操作符:
function initialize() {var socket = Rx.DOM.fromWebSocket(‘ws://127.0.0.1:8080‘);...
  • 上面的處理代碼中,fromWebSocket建立了一個Subject,它作為一個接受和發送訊息到WebSocket server的服務提供者,通過訂閱socket,我們將受到伺服器發給我們的任何訊息。
  • 現在可以發送我們接收的伺服器發送的地震訊息了:
quakes.bufferWithCount(100).subscribe(function(quakes) {console.log(quakes);var quakesData = quakes.map(function(quake) {return {id: quake.properties.net + quake.properties.code,lat: quake.geometry.coordinates[1],lng: quake.geometry.coordinates[0],mag: quake.properties.mag};});? socket.onNext(JSON.stringify({quakes: quakesData }));});
  • 我們也建立一個來自伺服器訊息的訂閱者:
socket.subscribe(function(message) {console.log(JSON.parse(message.data));});
  • 現在我們重新載入瀏覽器,這個client訊息將會在terminal上出現的:

  • 古怪的!這個瀏覽器可以發送命令到伺服器當它開始接收遠端JSONP資源的地震。到目前為止,這個server完全忽略了這些訊息。回到我們的tweet流的代碼並做些什麼。

  • 首先,我們將從browser client上連到那個message事件,它到達伺服器。無論何時,client發送了一條訊息,這個WebSocket伺服器將會發射一個message事件串連到這個訊息。這種情況下,這個內容是分層的對象。
  • 在onConnect函數裡我麼寫如下代碼:
var onMessage = Rx.Observable.fromEvent(ws, ‘message‘).subscribe(function(quake) {quake = JSON.parse(quake);console.log(quake);});
  • 如果我們重啟伺服器(在terminal中ctrl-c)並重載瀏覽器,我們可以看到地震的詳請,這些它們進來的將會子啊terminal上列印。這樣很好,我們現在可以搜尋跟tweets相關的地震了。
  • Retrieving and Sending Tweets
  • 我們正在使用基於Node.js twit流的Twitter用戶端去串連Twitter和搜尋tweets。從現在開始所有的代碼將會在onConnect函數的內部起作用,是由於它假設一個到WebSocket的串連已經建立了。現在讓我們初始化tweets的流:
var stream = T.stream(‘statuses/filter‘, {track: ‘earthquake‘,locations: []});
  • 這告訴我們Twit執行個體T開會Twitter的statues的流,以地震的keyword來過濾。當然,這是普通和不直接和現在正發生的地震相關的。注意到空的locations數組。它是經緯度的數組,通過earthquake這個詞,利用它們的地理位置過濾tweets。
    這很特別!讓我們訂閱到這個stream並開始發送tweets到瀏覽器:
Rx.Observable.fromEvent(stream, ‘tweet‘).subscribe(function(tweetObject) {ws.send(JSON.stringify(tweetObject), function(err) {if (err) {console.log(‘There was an error sending the message‘);}});});
  • 如果我們重啟伺服器並重新載入瀏覽器,我們在瀏覽器上收到tweets,並在在開發人員的布局的控制上列印這些推特。
  • 這些推特沒有通過地震位置倆過濾。為了實現這項,我們需要對收到的每條地震訊息作如下處理:
  • 取得每個地震中心的經緯度並建立一個限制盒子,它限定了我們認為和地震相關的推特的地理位置。
  • 累積所有的座標盒子,以便推特發送到client上並在地圖上描述素有相關的地震。
  • 每當我們收新地震的訊息,使用新做封裝更新twit流。
  • 如下便是:
Rx.Observable.fromEvent(ws, ‘message‘).flatMap(function(quakesObj){quakesObj = JSON.parse(quakesObj);return Rx.Observable.from(quakesObj.quakes);})? .scan([], function(boundsArray, quake) {? var bounds = [quake.lng - 0.3, quake.lat - 0.15,quake.lng + 0.3, quake.lat + 0.15].map(function(coordinate) {coordinate = coordinate.toString();return coordinate.match(/\-?\d+(\.\-?\d{2})?/)[0];});boundsArray.concat(bounds);? return boundsArray.slice(Math.max(boundsArray.length - 50, 0));})? .subscribe(function(boundsArray) {stream.stop();stream.params.locations = boundsArray.toString();stream.start();});
  • 這裡上面代碼一步步的發生的:
  • 1:我們又要使用scan了。每次我們需要累加結果並立即產生新的值,scan就是我們的朋友。這種情況下,我們將會在boundsArray數組中一直儲存地震的座標。
  • 2:從單個的地震中心的座標的經緯度中,我們建立一個包含西北、東南座標的的地區的數組。這些大致的界限建立了一個大型城市的矩形框。之後,我們使用了一個規律的運算式來限制每個座標兩位小數的精度,來遵循Twitter API的規範。
  • 3:我們串連產生的邊界到boundsArray,它包含之前的每個地震邊界。之後,我們取最近的25對邊界(這個數組裡面有50項),這是TwitterAPI的限制。
  • 4:自後,我們訂閱到Observable,在onNext函數中,我們重啟當前的twit流來重載更新位置,並通過我們新累存的位置數組來過濾,轉化為字串。
  • 在重啟伺服器和重新載入瀏覽器後,我們可以在我們的瀏覽器程式中收到相關的推特。到目前為值,我們可僅能在開發人員控制台看到原始的資料對象。下一部分,我們將通過HTML來在我們的儀錶上展示tweets。
  • Showing Tweets on the Dashboard
  • 現在我們沖伺服器收到tweets,僅僅遺留需要完成的是把它們在螢幕上顯示。我們將建立一個新的HTML元素在我們追加新來的tweets的地方。
<div id="tweet_container"></div>

我們將會跟新我們的socket Observable訂閱倆處理新的tweet對象並追加它們到剛建立的tweet_container元素上。

socket.map(function(message) { return JSON.parse(message.data); }).subscribe(function(data) {var container = document.getElementById(‘tweet_container‘);container.insertBefore(makeTweetElement(data), container.firstChild);});
  • 任何新的tweets將會出現在列表的最頂上,它們將會被makeTweetElement建立,一個建立tweet元素的簡單函數,並把我們傳遞的資料地位到上面:
function makeTweetElement(tweetObj) {var tweetEl = document.createElement(‘div‘);tweetEl.className = ‘tweet‘;var content = ‘<img src="$tweetImg" class="avatar" />‘ +‘<div class="content">$text</div>‘ +‘<div class="time">$time</div>‘;var time = new Date(tweetObj.created_at);var timeText = time.toLocaleDateString() + ‘ ‘ + time.toLocaleTimeString();content = content.replace(‘$tweetImg‘, tweetObj.user.profile_image_url);content = content.replace(‘$text‘, tweetObj.text);content = content.replace(‘$time‘, timeText);tweetEl.innerHTML = content;return tweetEl;}
  • 最後,我們使用一個有關的工具列,定位能給我們更多關於地震的地區結果的資訊的tweets。
Ideas for Improvements
  • 這個儀錶已經起作用了,但是還有許多提高可以做。如下是一些更好的建議:
  • 添加更多的地震資料,USGS是一個很好的資源,但是它主要提供發生在美國的。匯聚全世界的地震將會更加有趣,而不僅僅是美國,並把它們在地圖上顯示出來。這樣,你需要使用merge和mergeAll來幫忙了,並使用distinct這個選擇函數來去重。
  • 無論何時使用者點擊了tweet,在地圖上圈出相關的地震。這將會包含對伺服器地震tweet的歸類,你將有可能使用groupBy操作符來歸類tweets到一個特定的地理地區。

RxJS入門(8)----建立一個完整的web application

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.