用 Socket.io 處理 NodeJS 和 AngularJS 間的 tweet

這篇文章裏面,咱們學習一下,怎麼用 Socket.io 來流化處理一些舊金山周邊的 tweet,在 nodejs 應用和 angularjs 應用之間。咱們爲了從 nodejs 應用拿到 tweet, 咱們用的是 Twitter API 的 nodejs 客戶端: Twitnode

首先,咱們須要在 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 發送過來的消息了。

相關文章
相關標籤/搜索