使用哪个WebSocket库与Node.js配合使用?

454

目前有大量的websocket库可供node.js使用,最受欢迎的似乎是:

plethora of websocket libraries

然而,我找不到任何它们之间的确切比较……据说Socket.io很棒,但现在已经过时并且编译失败。ws和websocket-node都声称是最快的。engine.io似乎很新,但比轻量级的备选方案更为臃肿。
如果我们或其他人能够提供一个指南,介绍何时使用哪个socket库以及它们之间的比较,那将非常棒。

264
如果这个问题被关闭了,那么这样的问题应该去哪里问呢?因为答案非常有用...很遗憾这样一个重要的问题不能留在这里。 - balupton
16
社区Wiki值得欢呼,这意味着尽管问题已关闭不再接受新的答案,但我们仍然可以改进以下社区Wiki答案 :) - balupton
17
我同意,我希望看到这种类型的问题不仅被允许,而且被鼓励提出。虽然这些问题也许在未来一年内不太相关,但在那之前它们会拯救世界。 - John Little
1
@balupton,你能否告诉社区你的选择以及是否满意?是socket.io吗? - C graphics
3
最近我使用Primus和ws,因为ws已经满足我的需求,如果我需要更强大的功能,我只需更换底层库并保持相同的API即可,这得益于Primus。效果非常好。 - balupton
显示剩余3条评论
3个回答

418

通过这个社区Wiki回答来推动项目。欢迎您编辑并对其进行改进。

  • ws WebSocket服务器和客户端用于node.js。 如果不是最快的库之一,也是最快的库之一。

  • websocket-node WebSocket服务器和客户端用于node.js

  • websocket-driver-node WebSocket服务器和客户端协议解析器node.js-在faye-websocket-node中使用

  • faye-websocket-node WebSocket服务器和客户端用于node.js-在faye和sockjs中使用

  • socket.io WebSocket服务器和客户端用于node.js + 浏览器的客户端 +(v0具有从新到旧的后备,v1的Socket.io使用engine.io)+通道-在stack.io中使用。 客户端库在断开连接后会尝试重新连接。

  • sockjs WebSocket服务器和客户端用于node.js和其他+适用于浏览器的客户端+从最新到最旧的后备

  • faye WebSocket服务器和客户端用于node.js和其他+适用于浏览器的客户端+后备+支持其他服务器端语言

  • Deepstream.io是一个可扩展的实时服务器,处理WebSockets和TCP连接,并提供数据同步、发布/订阅和请求/响应功能。

  • SocketCluster是一个WebSocket服务器集群,利用您机器上的所有CPU核心。例如,如果您使用具有32个核心的大型Amazon EC2实例,则可以在单个实例上处理几乎32倍的流量。

  • Primus为大多数上述库提供了通用API,便于轻松切换和提高稳定性。

  • 何时使用:

    • 当您想要在客户端使用本机WebSocket实现时,请使用基本的WebSocket服务器,但要注意浏览器不兼容性问题

    • 当您关心浏览器回退时,请使用回退库

    • 当您关心频道时,请使用完整功能的库

    • 当您不知道该使用什么、没有心情因项目需求变化而重写应用程序,或需要更多的连接稳定性时,请使用Primus

    测试位置:

    Firecamp是一个GUI测试环境,可用于测试SocketIO、WS和所有主要的实时技术。在开发过程中调试实时事件。


    10
    谢谢你提供详细的答案。能否解释一下第三点的使用情况?这个点指的是哪些通道?我刚接触WebSockets,正在尝试理解在我的情况下应该使用哪一个通道。 - Akshat Jiwan Sharma
    2
    Autobahn/WAMP怎么样? - Emile Cormier
    1
    现在.js离世后所有可用选项的好列表。 - Rahul Prasad
    5
    对于ws的一个小细节是它需要Python。因此,如果您在Docker容器或其他地方部署它,您需要有Python可用来使用ws - AntouanK
    Deepstream.io 服务器不再在 Node.js 上运行,现在您必须将其作为单独的服务运行,然后添加 Deepstream.io 客户端到 Node.js 上以与服务器通信。 - Luke Brown
    显示剩余4条评论

    42

    更新:自那时起,提到的库已发布了更新版本,因此本答案已过时。

    Socket.IO v0.9已经过时且有些不稳定,而Engine.IO是其临时接替者。Socket.IO v1.0(即将发布)将使用Engine.IO,并且比v0.9要好得多。我建议您在Socket.IO v1.0发布之前使用Engine.IO。

    "ws"不支持回退,因此如果客户端浏览器不支持WebSockets,则无法正常工作,不像Socket.IO和Engine.IO在WebSockets不可用时则使用长轮询等。然而,“ws”目前似乎是最快的库。

    请参阅我的文章,比较Socket.IO、Engine.IO和Primus:https://medium.com/p/b63bfca0539


    这让我想起了通常的 Node.js 0.12 立即发布 … 他们也声称已经几个月了。所以,可能我们还需要等待和观察… - Golo Roden
    1
    你有关于Autobahn/WAMP(http://wamp.ws/)的任何见解或经验吗? - Emile Cormier
    6
    Socket.IO发布了v1版本。Engine.io并不是它的替代品,但在Socket.IO内部作为传输协议使用 - 它抽象了端点(xhr、ws)之间的实际通信,并具有简单的数据包格式。Socket.IO提供了更丰富的API,感觉就像通过无线电发送事件一样。 - hammett

    34

    对我来说,npm ws 是最好的选择。我觉得它更加简洁明了而且不会给人带来额外的麻烦。使用它也非常容易将 websockets 和 rest 服务结合起来。在这篇文章中,我分享了一些简单的代码。

    var WebSocketServer = require("ws").Server;
    var http = require("http");
    var express = require("express");
    var port = process.env.PORT || 5000;
    
    var app = express();
        app.use(express.static(__dirname+ "/../"));
        app.get('/someGetRequest', function(req, res, next) {
           console.log('receiving get request');
        });
        app.post('/somePostRequest', function(req, res, next) {
           console.log('receiving post request');
        });
        app.listen(80); //port 80 need to run as root
    
        console.log("app listening on %d ", 80);
    
    var server = http.createServer(app);
        server.listen(port);
    
    console.log("http server listening on %d", port);
    
    var userId;
    var wss = new WebSocketServer({server: server});
        wss.on("connection", function (ws) {
    
        console.info("websocket connection open");
    
        var timestamp = new Date().getTime();
        userId = timestamp;
    
        ws.send(JSON.stringify({msgType:"onOpenConnection", msg:{connectionId:timestamp}}));
    
    
        ws.on("message", function (data, flags) {
            console.log("websocket received a message");
            var clientMsg = data;
    
            ws.send(JSON.stringify({msg:{connectionId:userId}}));
    
    
        });
    
        ws.on("close", function () {
            console.log("websocket connection close");
        });
    });
    console.log("websocket server created");
    

    如何在连接方法中获取请求的URL?wss.on("connection", function (ws) { // 一些代码,使用console.log(ws.???)来获取URL... } - Opalosolo
    在ajax请求中没有请求URL。Javascript库使用地址(例如127.0.0.1:8080或anything.com:7777等)打开到您的Web套接字服务器的连接。如果听起来令人困惑,请尝试通过一些简单的Web套接字教程进行学习。 - MFAL
    7
    实际上,WebSocket 端点也有 URL,它们以 ws 开头,例如 ws://myserver.com。是的,它们也可以配置成使用 80 和 443 端口。使用类似 Nginx 的反向代理,您可以将 WebSocket 协议的 URL 路由到普通 HTTP 协议之外的另一个端口。 - Prahlad Yeri
    如果您需要,可以模拟路由。 - Lucas Tettamanti
    1
    使用 express-ws 可以在 Express 应用程序中添加 ws 路由。 - Dmitry Masley
    点赞!你会如何测试这段代码是否有效? - PirateApp

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接