這篇文章裏面,咱們學習一下,怎麼用 Socket.io 來流化處理一些舊金山周邊的 tweet,在 nodejs 應用和 angularjs 應用之間。咱們爲了從 nodejs 應用拿到 tweet, 咱們用的是 Twitter API 的 nodejs 客戶端: Twit 。node
首先,咱們須要在 Twitter developers 建立一個應用。建立一個只須要讀權限的應用。對咱們的應用來講足夠了。如今,生成你的訪問 token。 你須要四個 token: Application API Key, Application API Secret, Access Token 和 Access Token Secret。git
你能夠從 Github 拿到源碼,從這裏訪問在線例子。angularjs
拿到舊金山周邊的 tweets: 經過 nodejs 和 Twitgithub
爲了在 nodejs 中拿到 tweets, 咱們須要配置 Twit。express
<!-- lang: js --> var Twit = require('twit'); var TWEETS_BUFFER_SIZE = 3; var T = new Twit({ consumer_key: 'API Key', consumer_secret: 'API Secret', access_token: 'Access Token', access_token_secret: 'Access Token Secret' })
而後,咱們能夠打開一個流,指向是 /status/filter, 加上位置參數和 tweet 事件。當有推動來的時候,這個事件就會被觸發。服務器
<!-- lang: js --> console.log("Listening for tweets from San Francisco..."); var stream = T.stream('statuses/filter', { locations: [-122.75,36.8,-121.75,37.8] }); var tweetsBuffer = []; stream.on('connect', function(request) { console.log('Connected to Twitter API'); }); stream.on('disconnect', function(message) { console.log('Disconnected from Twitter API. Message: ' + message); }); stream.on('reconnect', function (request, response, connectInterval) { console.log('Trying to reconnect to Twitter API in ' + connectInterval + ' ms'); }) stream.on('tweet', function(tweet) { if (tweet.geo == null) { return ; } //Create message containing tweet + username + profile pic + geo var msg = {}; msg.text = tweet.text; msg.geo = tweet.geo.coordinates; msg.user = { name: tweet.user.name, image: tweet.user.profile_image_url }; console.log(msg); });
在 tweet 事件裏面咱們經過接收到的數據,建立一個只包含推的內容,座標,用戶及用戶照片的信息。如今咱們看看怎麼用 Socket.IO 流化這個推,在 nodejs 和 angularjs 之間交流。app
Streaming tweets with Socket.IOsocket
首先咱們要配置 socket.io ,讓它和 express 服務一塊兒工做:學習
<!-- lang: js --> var express = require('express'); var app = express(); var server = app.listen(3000); var io = require('socket.io').listen(server);
如今,若是轉向到 localhost:3000/socket.io/socket.io.js 咱們能夠拿到 socket.io 的客戶端。咱們只須要用咱們的 socket.io 向全部連接上的客戶端廣播信息就能夠了。所以咱們要改一下 tweet 事件:ui
<!-- lang: js --> stream.on('tweet', function(tweet) { if (tweet.place == null) { return ; } //Create message containing tweet + username + profile pic + location var msg = {}; msg.text = tweet.text; msg.location = tweet.place.full_name; msg.user = { name: tweet.user.name, image: tweet.user.profile_image_url }; //push msg into buffer tweetsBuffer.push(msg); //send buffer only if full if (tweetsBuffer.length >= TWEETS_BUFFER_SIZE) { //broadcast tweets io.sockets.emit('tweets', tweetsBuffer); tweetsBuffer = []; } });
這個方案能用,但是不是最好的一個。若是你沒有服務端連接,你仍是會把 tweet 處處亂髮。咱們得考慮帶寬。爲了避免處處發騷,咱們得記錄已連接客戶端。若是這個數目是 0 ,咱們就不轉發了。
<!-- lang: js --> var nbOpenSockets = 0; io.sockets.on('connection', function(socket) { console.log('Client connected !'); if (nbOpenSockets <= 0) { nbOpenSockets = 0; console.log('First active client. Start streaming from Twitter'); stream.start(); } nbOpenSockets++; socket.on('disconnect', function() { console.log('Client disconnected !'); nbOpenSockets--; if (nbOpenSockets <= 0) { nbOpenSockets = 0; console.log("No active client. Stop streaming from Twitter"); stream.stop(); } }); });
在 AngularJS 方經過 Socket.IO 接收信息
nodejs 應用能夠取得推特,而後廣播轉發到已連接客戶端。咱們來看看如何建立一個 AngularJS 客戶端。首先咱們須要創建一個 service,用來連接到咱們的服務器,和處理接收事件:
<!-- lang: js --> appServices.factory('socket', function ($rootScope) { var socket = io.connect('http://localhost:3000'); return { on: function (eventName, callback) { socket.on(eventName, function () { var args = arguments; $rootScope.$apply(function () { callback.apply(socket, args); }); }); } }; });
而後咱們能夠用這個 service 來監聽服務端廣播出來的 tweet 事件:
<!-- lang: js --> $scope.tweets = []; socket.on('tweets', function (data) { $scope.tweets = $scope.tweets.concat(data); });
碉堡了,咱們的 Angular 應用經過 Socket.IO 接收到了從 nodejs 發送過來的消息了。