理想情况下,您可以使用
WebSockets
,但备选方案是使用长轮询 ajax。
您可以使用长轮询技术进行聊天。这意味着您向服务器发送一个(ajax)请求,并且服务器将保持这个请求,直到有一些数据需要发送。
因此,客户端定期轮询服务器,如果服务器没有新消息,则保持您的请求。如果它有消息,则将其发送回客户端,客户端将再次轮询服务器。
[[伪代码]]
// Client.js
var Socket = function(ip, port, name) {
this.ip = ip;
this.port = port;
this.name = name;
this._cbs = [];
this._poll();
};
Socket.prototype._poll = function() {
var that = this;
var timer = setTimeout(function() {
this._poll();
}, 5000);
$.ajax({
type: "GET",
timeout: 5000,
data: {
name: this.name
},
url: this.ip + ":" + this.port,
success: function(data) {
clearTimeout(timer);
for (var i = 0; i < that._cbs.length; i++) {
that._cbs[i](data);
}
that._poll();
}
});
};
Socket.prototype.on = function(event, cb) {
if (event === "message") {
this._cbs.push(cb);
}
};
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!");
// 服务器文件
var url = require("url");
var events = require("events");
var clients = {};
var emitter = new events.EventEmitter();
http.createServer(function(req, res) {
var data = url.parse(req.url, true).query;
if (data.name && !clients[data.name]) {
clients[data.name] = [];
}
if (data.message) {
for (var k in clients) {
clients[k].push(data.name + " : " + data.message);
}
emitter.emit("new-data");
} else if (clients[data.name].length > 0) {
for (var i = 0; i < clients[data.name].length; i++) {
res.write(clients[data.name].shift());
};
res.end();
} else {
var cb = function() {
for (var i = 0; i < clients[data.name].length; i++) {
res.write(clients[data.name].shift());
};
res.end();
clearTimeout(timer);
}
emitter.once("new-data", cb);
var timer = setTimeout(function() {
emitter.removeListener(cb);
res.end();
}, 4500);
}
}).listen(8081);
更好的推送技术是使用服务器端事件。在这里可以看到一个示例。不过这需要浏览器支持(我认为是Chrome和Opera)。