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

How to develop a large chat application with Socket.io and Node.js

本文关键字:开发 大型 聊天 应用程序 js Node 何使用 Socket io      更新时间:2023-09-26

在过去的几个月里,我一直在与Socket.io合作,开发一个相当复杂的聊天应用程序,其中包括聊天室、踢馆/禁止/主持人/朋友等。

在开发过程中,我已经多次重写该应用程序,但我仍在与代码作斗争。

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

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

  • 主持人点击启动按钮->将事件发送到服务器
  • 服务器将用户名与套接字配对(或者只向所有用户广播并在客户端进行筛选)->向他发送kick事件
  • 用户向服务器发出一个注销事件,并显示一条他被踢的消息(注销只是我惩罚的实现)
  • 该用户将从聊天室的用户列表中删除->将当前用户列表发送给聊天室中的所有用户

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

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

是我做错了什么,还是这个回调地狱是在没有办法绕过的情况下使用websocket的结果

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

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

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

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

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

将用户踢出房间:

  • 主持人单击"删除"按钮(发射应包含房间ID和用户ID)
  • 服务器代码将用户从Room对象中删除,并向房间中的每个用户发送userID被踢出的消息。如果您之前有用户的套接字连接(roomID),则服务器代码如下所示:

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

仅此而已。在客户端代码中,您应该收到这个"踢"的事件,并有这样的代码:

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

你不应该让客户端发出他要离开的消息,因为恶意用户可能会编写一个无视禁令的客户端。

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

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

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

  • 不要只研究代码。想想人们会如何直接沟通。客户端是发送信息的人,服务器是邮局。稍后翻译代码中的逻辑
  • 确保服务器是唯一可以控制的服务器,客户端只发出命令并显示状态,而不执行任何逻辑操作

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

披露:我是独家新闻的开发者。

我或多或少也遇到了同样的问题,它可以归结为通常的回调金字塔,可以用许多库来解决(有几十个,看看就知道了。

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

这是一个简单的lib,它试图像所有其他异步lib一样提供帮助,以具有一些个人风格的步骤为基础进行建模。看看这些例子,它可能适合你的需要。

你也可以看看derby.js。它是一个非常类似于meter的框架,但建立在所有node.js的"好东西"上,如npm、socket.io、express等。derby包括一个名为Racer的强大数据同步引擎,它可以在浏览器、服务器和数据库之间自动同步数据。他们甚至有一个基本的聊天示例。

Meteor使用了许多自己的技术(光纤、自己的包管理器)。就像流星德比仍处于阿尔法阶段,但在上一次比赛中获得了很多吸引力。Airbnb最近宣布,他们将考虑在未来实施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://stackoverflow.com/questions/10374113/meteor-vs-derbyjs

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

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

自我诊断是你的朋友。JavaScript是一种动态语言,没有一个值得注意的类型系统,它屏蔽了null对象;只有大量的自动测试才能确保质量。但正如你所说,测试可能真的很难。

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

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