上接(7)
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'
});
function onConnect(ws) {
console.log('Client connected on localhost:8080');
}
var Server = new WebSocketServer({ port: 8080 });
Rx.Observable.fromEvent(Server, 'connection').subscribe(onConnect);
function initialize() {
var socket = Rx.DOM.fromWebSocket('ws://127.0.0.1:8080');
...
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));
});
古怪的!这个浏览器可以发送命令到服务器当它开始接收远程的JSONP资源的地震。到目前为止,这个server完全忽略了这些消息。回到我们的tweet流的代码并做些什么。
var onMessage = Rx.Observable.fromEvent(ws, 'message')
.subscribe(function(quake) {
quake = JSON.parse(quake);
console.log(quake);
});
var stream = T.stream('statuses/filter', {
track: 'earthquake',
locations: []
});
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');
}
});
});
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();
});
<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);
});
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;
}