理想的にはWebSockets
を使用しますが、代替方法はajax long pollingです。
ロングポーリングと呼ばれる手法を使用してチャットを行うことができます。これは、サーバーに(ajax)リクエストを行い、送信するデータが残るまでサーバーはこの要求を保持し続けることを意味します。
クライアントが定期的にサーバーをポーリングするので、サーバーに新しいメッセージがない場合は、ユーザーの要求が保持されます。メッセージがあれば、それをクライアントに送り返し、クライアントはサーバーを再びポーリングします。
[[擬似コード]]
// Client.js
var Socket = function(ip, port, name) {
this.ip = ip;
this.port = port;
this.name = name;
this._cbs = [];
this._poll();
};
// Call the server periodically for data.
Socket.prototype._poll = function() {
var that = this;
// if the server does not return then call it again
var timer = setTimeout(function() {
this._poll();
}, 5000);
$.ajax({
type: "GET",
timeout: 5000,
data: {
name: this.name
},
url: this.ip + ":" + this.port,
success: function(data) {
// server returned, kill the timer.
clearTimeout(timer);
// send the message to the callback.
for (var i = 0; i < that._cbs.length; i++) {
that._cbs[i](data);
}
// call the server again
that._poll();
}
});
};
// Add a callback for a message event
Socket.prototype.on = function(event, cb) {
if (event === "message") {
this._cbs.push(cb);
}
};
// Send a message to the server
Socket.prototype.send = function(message) {
$.ajax({
data: {
message: message,
name: this.name
},
type: "GET",
url: this.ip + ":" + this.port
});
};
var socket = new Socket('192.168.1.1', '8081', "Raynos");
socket.on("message", function(data) {
console.log(data);
});
socket.send("Hello world!");
//より良いプッシュ技術はServer-side eventsだろう
var url = require("url");
var events = require("events");
// store messages for clients
var clients = {};
var emitter = new events.EventEmitter();
http.createServer(function(req, res) {
// get query string data
var data = url.parse(req.url, true).query;
// if client is not initialized then initialize it.
if (data.name && !clients[data.name]) {
clients[data.name] = [];
}
// if you posted a message then add it to all arrays
if (data.message) {
for (var k in clients) {
clients[k].push(data.name + " : " + data.message);
}
// tell long pollers to flush new data.
emitter.emit("new-data");
} else if (clients[data.name].length > 0) {
// else empty the clients array down the stream
for (var i = 0; i < clients[data.name].length; i++) {
res.write(clients[data.name].shift());
};
res.end();
// long polling magic.
} else {
var cb = function() {
for (var i = 0; i < clients[data.name].length; i++) {
res.write(clients[data.name].shift());
};
res.end();
// kill that timer for the response timing out.
clearTimeout(timer);
}
// when we get data flush it to client
emitter.once("new-data", cb);
var timer = setTimeout(function() {
// too long has passed so remove listener and end response.
emitter.removeListener(cb);
res.end();
}, 4500);
}
}).listen(8081);
をserver.js。 example of it hereを参照してください。これはブラウザのサポートを必要とします(Chromeとオペラは私が思う)。
しかし、メッセージはクライアントにどのように送信されるのですか?これは興味深いですが、これは面白いですが、node.jsには関係ありません:)しかし、PHPプログラマとしては面白そうです – Adam
クライアントはサービスに加入すると、キューが作成されます他のクライアントから送信されたメッセージクライアントがメッセージを送信すると、それは他の各サブスクライバのキューに追加されます。次に、クライアントは、独自のキューに追加された保留中のメッセージを要求します。 –
WebSocket(HTML5の機能)を使用すると、クライアントは、サーバーがクライアントにメッセージを「プッシュ」するために使用できるWebサーバーへの双方向ソケットを開くことができます。この機能がない場合、クライアントはAJAXを介してサーバーにポーリングメッセージをポーリングします。サーバーはmsgsをプッシュしません(WebSocketが存在しないため)、ネイティブ機能はありません。これがsocket.ioがとても有用な理由です。クライアントがWebソケットをサポートしている場合、クライアントはそれらを使用します。そうでなければ、それは長いポーリングに落ちる他の多くの手段を試みる。 –