4

私は Socket.io を使用して、Twitter のストリーミング API を使用してライブ ツイートをユーザーにストリーミングしています (私の実装は多かれ少なかれこのチュートリアルに基づいています)。

問題は、接続イベントが Socket.io によって起動されるたびに、新しく接続されたクライアントによって、サーバーに接続されている他のすべてのクライアントが更新を停止することです。私が試したすべてのハックを実行するには時間がかかりすぎますが、問題は Socket.io による複数のクライアント (デフォルトで有効) からの接続の多重化が複数のクライアントまたは接続が同じ基礎となるソケットを共有できるようにするためのパフォーマンスの向上。要するに、接続の多重化がなければ、新しい接続がこのように古い接続に影響を与える可能性はないと思うので、これが当てはまると思います。つまり、新品であれば、独自の基礎となる (TCP) ソケットとの独立した接続は、クライアントが接続するたびに作成されました。一方の接続は他方の接続について何も知らず、現在発生している他のクライアントの状態に影響を与えることができないため、これが発生することは不可能です。これはまた、多重化機能を単に無効にすることが、この問題を回避する最も簡単な方法であると信じさせます。なぜなら、Node.js は、非常に適切に処理する必要がある可能性が高いすべての同時実行性を既に処理しているため、スケーリングについて心配していないからです。

私は Socket.io のドキュメントを調べましたが、接続を "逆多重化" する機能が API を介して公開されている場所を確認できませんでした。

以下の私のコードはかなり標準的でシンプルです。ただし、明確にするために、問題は、新しいクライアントが Socket.io に接続するたびに、他のすべてのクライアントが新しいツイートの受信を停止し、ブラウザーを更新しない限り更新が古いクライアントにプッシュされなくなることです。その場合、新しく更新されたクライアントが開始されます。更新して新しいツイートを再度受信しますが、まだ接続されている他のクライアントは更新を停止します。

サーバー側コード:

// Code also uses ntwitter (https://github.com/AvianFlu/ntwitter) as an abstraction over Twitter's Streaming API
io.sockets.on('connection', function (socket) {
  tweet.stream('statuses/filter', { track : 'new orleans' }, function (stream) { 
    stream.on('data', function (data) {
      // The following lines simply pre-process data sent from Twitter so junk isn't
      // unnecessarily sent to the client.
      if (data.user) {
         tweets = {
         text  : data.text,
         image : data.user.profile_image_url,
         user  : data.user.name
         };
         var t = JSON.stringify(tweets);
         console.log(t);
         socket.send(t);
      }  
    });
  });
});

クライアント側コード

// Notice the option that I passed in as the second argument. This supposedly forces every 
// new client to create a new connection with the server but it either doesn't work or I'm 
// implementing it incorrectly. It is the very last configuration option listed in the 
// documentation linked to above.
var socket = io.connect('http://' + location.host, {'force new connection' : true });
socket.on('message', function (tweet) {
  var t = JSON.parse(tweet);
  if (t.image) {
    $('.hero-unit').prepend('<div class="media"><a class="pull-left" href="#"><img class="media-object" alt="64x64" style="width: 64px; height: 64px;" src="' + t.image + '"></a><div class="media-body"><h4 class="media-heading">' + t.user + '</h4>' + t.text + '</div></div>');
  } 
});

私がこれを間違って考えている場合、またはコードに何か問題がある場合は、どんな提案も歓迎します。また、追加の詳細があれば返信させていただきます。

4

1 に答える 1

0

私はこのようなことを試してみます

サーバ側:

io.sockets.on('connection', function (socket) {
    //Other Connectiony goodness here.
    });
});

tweet.stream('statuses/filter', { track : 'new orleans' }, function (stream) { 
    stream.on('data', function (data) {
      // The following lines simply pre-process data sent from Twitter so junk isn't
      // unnecessarily sent to the client.
      if (data.user) {
         tweets = {
         text  : data.text,
         image : data.user.profile_image_url,
         user  : data.user.name
         };
         var t = JSON.stringify(tweets);
         console.log(t);
         io.sockets.emit("tweet", t);
      }  
});

クライアント側:

var socket = io.connect('http://' + location.host, {'force new connection' : true });
socket.on('tweet', function (tweet) {
  var t = JSON.parse(tweet);
  if (t.image) {
    $('.hero-unit').prepend('<div class="media"><a class="pull-left" href="#"><img class="media-object" alt="64x64" style="width: 64px; height: 64px;" src="' + t.image + '"></a><div class="media-body"><h4 class="media-heading">' + t.user + '</h4>' + t.text + '</div></div>');
  } 
});

基本的に、Twitter からのストリームをソケットの外に置き、新しいツイートemitで、接続されているすべての人にメッセージを送信します。

于 2013-11-01T15:41:10.793 に答える