这篇文章里面,咱们学习一下,怎么用 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 发送过来的消息了。