11

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

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

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

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

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

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

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

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

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

4

5 回答 5

7

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

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

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

于 2012-09-23T17:47:19.187 回答
3

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

将用户踢出房间:

  • 版主点击删除按钮(发射应包含房间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 来启动屏幕,我无法想象它会变得更简单。尤其是不要使用一些“魔法”库来隐藏我的所有通信,并肯定会引入它自己的一组等待被发现和修复的错误。

于 2012-09-30T00:24:33.427 回答
0

披露:我是scoop的开发者。

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

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

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

于 2012-09-26T13:59:02.820 回答
0

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

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

更多信息:

于 2012-09-27T10:21:56.137 回答
0

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

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

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

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

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

于 2012-09-29T22:32:50.097 回答