0

これはすでに何千回も尋ねられているに違いありませんが、満足のいく答えが見つからないので、できるだけ明確にして、もう一度試してみます.

私はクリーンな Express から始めています。通常、次の端末コマンドを介して実行されます。

user$ express
user$ npm install

次に、socket.io のインストールを次のように進めます。

user$ npm install socket.io --save

私の main.js ファイルには、次のものがあります。

//app.js
var express  = require('express'),
  http     = require('http'),
  path     = require('path'),
  io       = require('socket.io'),
  routes   = require('./routes');

var app = express();

socket.io サーバーを Express サーバーに接続して起動します。

//app.js
var server = http.createServer(app).listen(app.get('port'), function(){
  console.log('express server started!');
});

var sIo = io.listen(server);

私が今やっていることは、Express が動作する通常のルートを設定することです:

//app.js
app.get('/', routes.index);
app.get('/send/:recipient/:text', routes.sendMessage);

さて、私は物事を整理しておくのが好きなので、socket.io コードを別のファイルに入れたいので、通常のコードを使用する代わりに:

//app.js
sIo.sockets.on('connection', function(socket){
  console.log('got a connection');
});

以下を使用して、ソケットとsIo オブジェクトの両方にアクセスできるようにします (そのオブジェクトにはすべての接続情報が含まれているため (重要))。

//app.js
sIo.sockets.on('connection', function(socket){
  routes.connection(sIo, socket);
});

// index.js (./routes)
exports.connection = function(sIo, socket){
  console.log('got a connection.');
};

このようにして、すべての socket.io ジョブをここで実行できます。sIo オブジェクトからすべてのクライアント情報にアクセスできることはわかっていますが、もちろん、セッション データに関する情報は含まれていませ

私の質問は次のとおりです。

  1. ユーザーがメッセージを送信するために HTTP リクエストを作成し、ルートのハンドラーが次のようになっているとします。

    exports.sendMessage = function(req, res){ //ここで処理を行います };

これを socket.io で何かを「起動」してメッセージを送信するにはどうすればよいですか? メッセージやユーザーなどを追跡するなど、実行する必要がある基本的な作業をすべて知りたいわけではありません。何かを行うために socket.io を「起動」する方法を理解したいだけです。

  1. socket.io がメッセージを特定の人にのみ送信し、他の誰もメッセージを受信しないことを 100% 確実にするにはどうすればよいですか? 私が見る限り、sIo オブジェクトからセッション情報を取得する方法はありません。

前もって感謝します。

4

2 に答える 2

3

質問 1: 2 つを分離する最もクリーンな方法は、おそらくEventEmitterを使用することです。HTTP メッセージが着信したときに発行する EventEmitter を作成します。必要に応じて、イベントと共にセッション情報を渡して、メッセージを送信したユーザーに関連付けることができます。

// index.js (./routes)
var EventEmitter = require('events').EventEmitter;

module.exports.messageEmitter = messageEmitter = new EventEmitter();

module.exports.sendMessage = function(req, res) {
  messageEmitter.emit('private_message', req.params.recipient, req.params.text);
};

質問 2: 最初の接続が行われると、ソケットにアクセスできます。主にこの回答から借用した例:

var connect = require('connect'),
    userMap = {};

routes.messageEmitter.on('private_message', function(recipient, text) {
    userMap[recipient].emit('private_message', text);  
});

io.on('connection', function(socket_client) {
  var cookie_string = socket_client.request.headers.cookie;
  var parsed_cookies = connect.utils.parseCookie(cookie_string);
  var connect_sid = parsed_cookies['connect.sid'];
  if (connect_sid) {
    session_store.get(connect_sid, function (error, session) {
      userMap[session.username] = socket_client;
    });
  }

  socket_client.on('private_message', function(username, message) {
      userMap[username].emit(private_message, message)
  });
});

したがって、セッションのユーザー名とソケット接続の間のマップを作成しているだけです。メッセージを送信する必要があるときはいつでも、そのユーザーに関連付けられているソケットを簡単に検索し、ソケットを使用してメッセージを送信できます。切断、再接続、複数のタブでの接続などを処理するようにしてください。

于 2013-08-14T19:16:01.380 に答える
0

私はあなたが言っているようなものを構築しました。ユーザーがソケット要求を行うことができる場合、ソケットを介してメッセージをプッシュし、サーバーはそれをブロードキャストまたは送信します。ただし、ユーザーがソケットに接続できない場合は、sendMessage を呼び出して言っているように、http ポストを行います。私がやったことは、sendMessage をソケットから発射させるのではなく、クライアントに 5 秒ごとに ajax リクエストを実行させることです。これにより、新しいメッセージが返されます。メッセージのいずれかが socket.io 経由で受信されなかった場合は、それらをクライアント側配列に追加します。これは一種のセーフティ ネットとして機能するため、socket.io を常に完全に信頼する必要はありません。

以下の疑似コードを参照してください

クライアント

if canSendSocketMessage()
  sendSocketMessage(message)
else
  sendAjaxMessage(message)

setInterval( ->
  // ajax call
  getNewMessages()
), 5000

サーバ

ソケットのもの

socket.on 'message' ->
   saveMessage()
   socket.emit(message)

ajax エンドポイント

 app.post 'sendMessage'
    saveMessage()

 app.get 'getNewMessages'
    res.send getNewMessages()
于 2013-08-14T18:53:25.147 に答える