如何使用 Socket.io 和 Node.js 开发大型聊天应用程序 [关闭]

Posted

技术标签:

【中文标题】如何使用 Socket.io 和 Node.js 开发大型聊天应用程序 [关闭]【英文标题】:How to develop a large chat application with Socket.io and Node.js [closed] 【发布时间】:2012-08-30 08:21:44 【问题描述】:

在过去的几个月里,我一直在使用 Socket.io,开发了一个相当复杂的聊天应用程序,其中包含聊天室、踢/禁止/版主/朋友/等。

在开发过程中,我多次重写了应用程序,但我仍在努力编写代码。

我真的很喜欢 javascript,但我发现随着应用程序的增长,很难维护它。我已经阅读了大量关于如何编写聊天应用程序的“教程”,但它们都只涵盖了最基本的方面。 GitHub 上的所有示例应用程序也是如此,甚至是我在网络上找到的大多数聊天应用程序(其中大多数只是简单的 IM,没有任何用户管理)。

有些用例对我来说似乎太荒谬了,例如将用户踢出房间。

版主点击踢按钮 -> 向服务器发送事件 服务器将用户名与套接字配对(或仅向所有用户广播并在客户端过滤)-> 向他发送 kicked 事件 用户向服务器发出注销事件,并显示他被踢的消息(注销只是我的惩罚实现) 用户已从聊天室的用户列表中删除 -> 将当前用户列表发送给房间中的所有用户

这似乎并不太复杂,但是当我添加在客户端发生的所有回调来管理 UI 时(因为我使用 AngularJS,我使用事件在控制器之间进行通信),并且还有大量的回调服务器端,因为一切都是非阻塞的,我发现这很难测试。

客户端还有另一个问题,我必须在多个地方监听套接字事件,所以我必须有一种单例全局套接字对象,并在多个地方挂钩事件监听器。

是我做错了什么,还是这个回调地狱是使用 websockets 的结果而无法解决?

有没有什么方法可以让开发这样的应用程序变得更容易?例如 Socket.io 的替代技术?到目前为止我只找到了NowJS,它最后一次提交是在5个月前,还有meteor,它真的很酷,但是看网站它似乎并不稳定。

【问题讨论】:

【参考方案1】:

只需使用我的朋友的承诺。 jQuery 内置了它们,但在 nodejs 端,您可以使用 q 库。不要在没有它们的情况下编写异步代码!他们需要一点时间来适应,但是一旦你有了这种心态,编写异步代码就变得轻而易举了。

还有像async 这样的库,它们为您提供了有关回调代码的实用函数。但不要让人气欺骗了你。承诺是甜蜜的。

对于异步代码测试,您不需要比nodeunit 走得更远,它为您提供了一个简单的done() 函数,您可以在测试完成时调用它,因此它可以运行任意时间。

【讨论】:

你不需要使用jquery。我已经看到了一些其他的 JS 延迟库。所有这些都很棒的是,每个人都只返回一个对象,完成、失败和然后,并且大多数还有一个 when 函数。我希望这意味着它们彼此兼容。【参考方案2】:

哇,让我们把它分解成实际问题,因为我没有看到很多定义:

将用户踢出房间:

版主单击“删除”按钮(发送应包含房间 ID 和用户 ID)

服务器代码将用户从 Room 对象中移除,并向房间中的每个用户发出 userID 已被踢出的消息。如果您之前有用户的 socket join(roomID),那么服务器代码将如下所示:

sio.sockets.to(roomID).emit('kicked',  userID: uid );

就是这样。在客户端代码中,你应该会收到这个“被踢”的事件并且有这样的代码:

if (data.removedUserID == myUserID)
    alert('You have been kicked by moderator');
else
    removeUserFromList(userID);

您不应该让客户端发出他要离开的消息,因为恶意用户可以编写一个忽略禁止的客户端。

我必须在多个地方监听套接字事件

为什么? “多个地方”到底是什么意思?

有没有什么方法可以让开发这样的应用程序变得更容易?

不要只钻研代码。想想人们如何直接交流。客户端是发送消息的人,服务器是邮局。稍后在代码中翻译逻辑。 确保服务器是唯一受控制的服务器,客户端仅发出命令并显示状态而不执行任何逻辑。

我开发了一个 4000 位置的多人游戏,其中聊天只是其中的一小部分。我每天有大约 60.000 名用户在玩它。一切都是简单的 socket.io 代码,带有一些 Express/EJS 来启动屏幕,我无法想象它会变得更简单。尤其是不要使用一些“魔法”库来隐藏我的所有通信,并肯定会引入它自己的一组等待被发现和修复的错误。

【讨论】:

你有什么好的测试socketio的方法吗? @milan-babuskov,我在这里发布了一个我的问题:***.com/questions/23059711/…。你能指导我吗?【参考方案3】:

披露:我是scoop的开发者。

我或多或少有同样的问题,归结为通常的回调金字塔,可以用许多库来解决(有几十个,just take a look。

在我发现一个主要缺点之前,我对step 非常满意:你不能嵌套它们(一个调用更多步骤内容的步骤调用)。这对我来说非常重要,我不太喜欢所有其他异步库,因为它们提供了太多我无论如何都不会使用的功能,所以我写了scoop。

这是一个简单的库,它试图像所有其他异步库一样提供帮助,按照步骤建模并带有一些个人风格。查看示例,它可能适合您的需求。

【讨论】:

【参考方案4】:

您也可以查看derby.js。它是一个与meteor 非常相似的框架,但建立在所有node.js“好东西”上,如npm、socket.io、express 等。Derby 包含一个强大的数据同步引擎,称为Racer,它可以自动在浏览器、服务器、和一个数据库。他们甚至有一个basic chat example。

Meteor 使用了很多自己的技术(光纤、自己的包管理器)。就像流星德比还处于 alpha 阶段,但在最后一次获得了很多吸引力。 Airbnb 最近宣布他们将consider derby 用于未来的实施。

更多信息:

http://techcrunch.com/2012/07/27/move-over-meteor-derby-is-the-other-high-speed-node-js-framework-in-town/ http://blog.derbyjs.com/2012/04/14/our-take-on-derby-vs-meteor/ https://***.com/questions/10374113/meteor-vs-derbyjs

【讨论】:

【参考方案5】:

你的问题很难回答,但我可以向你保证,我能感受到你的痛苦......即使没有 node.js,回调也会很快变得棘手,而且异步测试真的很难做到。我想我应该说:很难做好,但这听起来像是我知道如何轻松做到,而我不知道。背景问题是异步开发很难,就像过去的并发编程一样。

我认为不同的 websocket 库不会帮助您,甚至完全避免使用 websocket。可能对您有所帮助的是使用一些技巧。上面的 Andy Ray 暗示了承诺;我没有广泛使用它们,但值得一试。

自我诊断是你的朋友。 JavaScript 是一种动态语言,没有值得称道的类型系统,并且会屏蔽空对象;只有大量的自动测试才能确保质量。但正如你所说,测试真的很难。

另一个技巧:疯狂地检测您的应用程序。发送检测事件并在测试中检查它们。我们围绕无头浏览器 (PhantomJS) 构建了一个很酷的测试套件,我们在其中使用 JavaScript 检查客户端是否发送了正确的事件;它可能很难调试,但它可以工作。

当然,通常的设计技巧会有所帮助:KISS、YAGNI 等,但我不会用它们侮辱你的智慧。祝你好运。

【讨论】:

以上是关于如何使用 Socket.io 和 Node.js 开发大型聊天应用程序 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何实现 Laravel、node.js、socket.io 和 redis 以使用数据库创建实时聊天/通知

如何使用 node.js 和 socket.io 通过 WebSockets 流式传输 MP3 数据?

如何使用 node.js 和 socket.io 将文件从 iPhone 发送到另一台 iPhone?

如何使用 Socket.io 和 Node.js 开发大型聊天应用程序 [关闭]

Socket.io 使用 node.js,根本没有 express?

node.js、socket.io 和 SSL