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

时间:2012-09-05 15:04:41

标签: javascript node.js websocket chat socket.io

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

在开发过程中,我已多次重写应用程序,但我仍在使用我的代码。

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

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

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

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

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

我做错了什么,或者这个回调是否是使用websockets而无法绕过它的结果?

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

5 个答案:

答案 0 :(得分:7)

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

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

对于异步代码测试,您不需要比nodeunit更远,它可以为您提供一个简单的done()函数,您可以在测试完成后调用它,因此只要您运行它就可以运行等。

答案 1 :(得分:2)

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

从房间踢开用户:

  • 主持人单击“删除”按钮(emit应包含roomID和userID)
  • 服务器代码将用户从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);

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

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

为什么呢? “多个地方”到底意味着什么?

有没有办法让像这样的开发应用程序更容易?

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

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

答案 2 :(得分:0)

披露:我是scoop的开发者。

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

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

这是一个简单的lib,试图帮助像所有其他异步库一样,以一些个人风格模仿。看看这些例子,它可能适合您的需求。

答案 3 :(得分:0)

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

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

更多信息:

答案 4 :(得分:0)

你的问题很难回答,但我可以向你保证,我感觉到你的痛苦......即使没有node.js,回调也会很快变得毛茸茸,异步测试真的很难做到。我想我应该说:很难做好,但这听起来好像我知道怎么做很容易而且我不知道。背景问题是异步开发很难,就像以前的并发编程一样。

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

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

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

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