1

node.jsとexpress.ioを使って簡単なチャットアプリを開発しています

接続しているクライアント (またはオンラインのチャット) のリストを常に表示したいと考えています。

express.io の docでは、新しいクライアントが部屋に入ると、接続されているクライアントのリストを「取得」する方法について明確な方法がありません。つまり、「ブロードキャスト」だけで「取得」はありません。

誰かがこれを以前にやったことがありますか?

どんな手がかりも本当に役に立ちます。

ありがとう!

編集:

@jibsalesの答えを試した後。私たちはほとんどそこにいると思います。クライアントが私に返すのは、実際のクライアントの配列ではなく、次の配列です。

[ { id: 'OWix3sqoFZAa20NLk304',
namespace: 
 { manager: [Object],
   name: '',
   sockets: [Object],
   auth: false,
   flags: [Object],
   _events: [Object] },
manager: 
 { server: [Object],
   namespaces: [Object],
   sockets: [Object],
   _events: [Object],
   settings: [Object],
   handshaken: [Object],
   connected: [Object],
   open: [Object],
   closed: [Object],
   rooms: [Object],
   roomClients: [Object],
   oldListeners: [Object],
   sequenceNumber: 496205112,
   router: [Object],
   middleware: [],
   route: [Function],
   use: [Function],
   broadcast: [Function],
   room: [Function],
   gc: [Object] },
disconnected: false,
ackPackets: 0,
acks: {},
flags: { endpoint: '', room: '' },
readable: true,
store: { store: [Object], id: 'OWix3sqoFZAa20NLk304', data: {} },
_events: 
 { error: [Function],
   ready: [Function],
   connection: [Function],
   NewChatPrivateLine: [Function],
   NewIdea: [Function],
   NewChatLine: [Function],
   NewPost: [Function] } } ]

機能は次のとおりです。

var app = require('express.io')();
app.io.route('connection', function(req) {
  req.io.join(req.data.room);
  var clients = app.io.sockets.clients(req.data.room);
  console.log(clients)
  app.io.room(req.data.room).broadcast('announce', {
    user: req.data.user,
    clients: clients
  }) 
});

配列にはいくつかの循環オブジェクトがあり、ブロードキャストできないため、これは実際にはエラー ( data = JSON.stringify(ev); TypeError: 循環構造を JSON に変換しています) を返します。

何かご意見は?

4

2 に答える 2

2

express.ioは単に と を接着expressしているだけなので、のドキュメントもsocket.io参照することを忘れないでください。socket.ioそうは言っても、socket.iov0.7 以降、この情報を取得するための API メソッドが用意されました。

var clients = io.sockets.clients('room'); // all users from room `room`

残念ながらexpress.io、coffeescript で書かれている (UGGGH!!!) ので、ソースを読むのに苦労していますが、モジュールが必要な場合はexpress.io、socket.io インスタンスも巻き上げられるようです。

var express = require('express.io');
var clients = express.io.sockets.clients('room'); // all users from room `room`

これが機能しない場合は、非常に独断的な API があるexpress.ioように見えるため、express と socket.io を使用した手動構成を捨てexpress.ioます。手動構成へのきれいなインターフェース/抽象化を作成するだけなので、それほど難しいことでexpress.ioはありません(上記が機能しない場合、このユースケースでは実際にあなたを傷つけています)。

私 (および他の多くの websocket コンシューマ) は、コミュニティのサポートがないために SockJS の socket.io を捨てたので、SockJS もチェックアウトします。言うまでもなく、xhr-polling にフォールバックすると、IE9 で重大なメモリ リークが発生します。

于 2014-02-10T17:33:54.540 に答える
1

最後に、@Brad によって提案された「タッキング」ソリューションを使用しました。それは最もエレガントではありませんが、私がそれを改善するのを手伝ってくれるなら、それは素晴らしいでしょう!!

これは最終的なコードです:

サーバ側

var app = require('express.io')();

//To broadcast the users online in room sent by the client
var clients = [];
app.io.route('connect', function (req) {
  req.io.leave(req.data.room).on('disconnect', function() {
    //To remove client from list when disconnected
    var index = clients.indexOf(req.data.user);
    if (index > -1) {
      clients.splice(index, 1);
    }
    app.io.room(req.data.room).broadcast('announce', {
      user: req.data.user,
      clients: clients
    }) 
  });
  req.io.join(req.data.room);
  //To avoid repeating the same client with several opened windows/tabs
  var index = clients.indexOf(req.data.user);
  if (index === -1) {
    clients.push(req.data.user); 
  }
  app.io.room(req.data.room).broadcast('announce', {
    user: req.data.user,
    clients: clients
  }) 
});

クライアント側

// Emit ready event with person name and predefined room for who's online
io.emit('connect', {
  room: room,
  user: user
});

//Get the signal from server and create your list
io.on('announce', function (data){
 //Do awesome stuff with data 
}); 
于 2014-02-11T10:31:19.217 に答える