Node.JS:如何创建 HTTP 聊天服务器

Node.JS: How to create a HTTP Chat Server?

本文关键字:创建 HTTP 聊天 服务器 JS 何创建 Node      更新时间:2023-09-26

使用带有TCP的网络流对象效果很好(如节点中的预设.js介绍视频),但是我应该如何在HTTP中执行此操作?

有没有办法访问http.createServer()中的套接字/客户端?或者有什么方法可以做到这一点?我试图从官方节点聊天演示代码中找出解决方案,但我真的不明白。

了解客户端 js,但是在我(作为客户端)通过 AJAX 向服务器端 js 发送消息后会发生什么?如何发送给服务器上的其他客户端?

请注意,我不想学习该过程的逻辑,所以我不想使用 socket.io 或任何其他框架、库、模块。

非常感谢您的任何帮助!

理想情况下,你只使用WebSockets但另一种选择是ajax长轮询。

您可以使用一种称为长轮询的技术来进行聊天。这意味着您向服务器发出 (ajax) 请求,服务器会保留此请求,直到它有一些数据要发送。

因此,客户端最终会定期轮询服务器,如果服务器没有新的消息,它只会保留您的请求。如果它有消息,它会将其发送回客户端,客户端将再次轮询服务器。

[

[伪代码]]

客户.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!");

服务器.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);

更好的推送技术是服务器端事件。在此处查看示例。不过,这确实需要浏览器支持(我认为是Chrome和opera)。

一种方法涉及客户端"订阅"充当消息分发者的通道。订阅后,客户端将收到发送到通道的每条消息的副本。

许多节点聊天服务依赖于 redis 的 pubsub 功能来处理从一个客户端到任意数量的客户端的消息分发。如果你想"自己动手",了解 redis 如何解决这个问题将是一个很好的开始。

如果你想知道长轮询的基本原理,那么试着看看这篇文章。我在那里总结了我自己的长轮询服务器的某些部分,我是如何实现它们的,这篇文章还包含指向其他资源的链接。它至少应该给你一个更大的图景,即轮询工作多长时间。

如果你想学习逻辑,以便从node.js中获得一些编码乐趣,而不是使用现有的解决方案,那么我建议从最简单和基本的实现逐步到更复杂的东西。不要试图从第一枪开始构建整个东西,因为这是失败的最可靠方法之一。