最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Node.JS: How to create a HTTP Chat Server? - Stack Overflow

programmeradmin5浏览0评论

With the Net Stream Object with TCP works great (as presetend in the node.js introduction video), but how should I do this in HTTP?

Is there a way to access sockets/clients within an http.createServer() ? Or what's the method to do it? I tried to figure out the solution from the official node chat demos souce code, but I don' really understand.

I understand the client side js, but what's happening after I(as a client) send a message trough AJAX, to the server side js? How can I send to the other clients who's on the server too?

Please note that I wan't to learn the logic of the process, so I don't want to use socket.io or any other frameworks, libraries, modules.

Thanks very much for any help!

With the Net Stream Object with TCP works great (as presetend in the node.js introduction video), but how should I do this in HTTP?

Is there a way to access sockets/clients within an http.createServer() ? Or what's the method to do it? I tried to figure out the solution from the official node chat demos souce code, but I don' really understand.

I understand the client side js, but what's happening after I(as a client) send a message trough AJAX, to the server side js? How can I send to the other clients who's on the server too?

Please note that I wan't to learn the logic of the process, so I don't want to use socket.io or any other frameworks, libraries, modules.

Thanks very much for any help!

Share Improve this question edited May 19, 2011 at 0:44 Adam Halasz asked May 18, 2011 at 23:26 Adam HalaszAdam Halasz 58.3k67 gold badges153 silver badges216 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 10

Ideally you just use WebSockets but the alternative is ajax long polling.

You can use a technique known as long polling to do the chat. This means you make an (ajax) request to the server and the server keeps hold of this request until it has some data left to send.

So the clients ends up periodically polling the server, if the server has no new messsages, it just keeps hold of your request. If it has a message it sends it back to the client and the client will poll the server again.

[[Pseudo Code]]

// 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.js

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);

A better push technology would be Server-side events. See an example of it here. This does require browser support though (Chrome and opera I think).

One way of doing it involves clients "subscribing" to a channel that acts as a distributor for messages. Once subscribed, a client then receives a copy of each message sent to the channel.

Many node chat services rely on redis' pubsub feature to handle this distribution of messages from one to any number of clients. If you wanted to "roll your own", understanding how redis solves this problem would be a great start.

If you want to know the basic principles of long polling then try to look at this article. I summarized there certain parts of my own long poll server, how I implemented them and the article also contains links to other resources. It should give you at least the bigger picture of how long polling works.

If you want to learn the logic in order to have some coding fun with node.js, and not to use existing solutions, then I would remend to go step by step from the most simple and basic implementation to more plex stuff. Don't try to build the entire thing from the first shot because it's one of the most surest way how to fail.

发布评论

评论列表(0)

  1. 暂无评论