【问题标题】:Chat application using websockets使用 websockets 的聊天应用程序
【发布时间】:2016-02-15 04:34:21
【问题描述】:

我已经能够使用 Websockets 在使用 https://github.com/ghedipunk/PHP-Websockets 的用户之间创建聊天应用程序。

服务器所做的是当每个用户连接到套接字时,将所有创建的套接字对象变量存储在一个数组中。因此,最终他创建了一个数组,其中包含有关所有用户与套接字对象的信息。并且他每次循环遍历数组来检索用户的对象,以便将消息发送到相应的套接字。

这对于少量用户来说没问题。但是我们如何处理大量用户呢?我想在数据库中存储套接字对象,但后来我遇到了这个:How to save php socket resource in database?

上面写着“套接字必须重新创建并且不能存储在数据库中”。

那么,除了重新创建之外,还有什么更好的选择吗?如果我必须重新创建套接字,我该如何使用 PHP-Websockets 库呢?

提前致谢。

【问题讨论】:

    标签: javascript php sockets


    【解决方案1】:

    使用唯一的 user_ids 或 device_ids。例如,会话 id,并将 thays 存储到 DB。然后,在订阅事件时发送 user_id,并仅向该用户发送消息。

    【讨论】:

    • 是的。但问题是我如何在不知道他们的套接字信息的情况下“向该用户发送消息”?有什么办法吗?
    • 当客户端连接到服务器时,他必须使用有效载荷中的 user_id 发出新事件(例如“注册”)。服务器处理此事件,将 user_id 存储在数据库中,并将套接字连接到 user_id。套接字信息 - 一直在内存中。服务器重新启动后,客户端会以任何方式断开连接,因此套接字将被销毁 - 没有理由将套接字处理程序保存在数据库中。
    • 任何连接的用户在连接后都会发出“注册”事件,所以你有关于所有个连接用户的信息并且可以向其中任何一个发送消息。
    • 那么,这是否意味着将套接字对象存储在数组中是明智的?不会有任何影响(比如 Facebook 使用 websockets,它的 websocket 服务器将被信息数组淹没。所以,每次你必须在数组中搜索相应用户的套接字对象。)我已经完成了注册事件和虽然存储 uid 部分。
    【解决方案2】:

    套接字无法保存在磁盘上,因为它是现有连接。如果您销毁活动对象,则连接将关闭,用户将断开连接。

    首先我想提醒您,内存和 CPU 可能不是什么大问题。 Node.js 解释器实际上速度惊人,而且 WebSocket 对象几乎不占用太多内存。您将首先面临其他问题,例如带宽问题、打开的连接过多等。

    我能想到的可能的调整:

    多线程 - 产生子进程

    您可以在 node.js 进程之间共享套接字,如下所述:https://nodejs.org/api/child_process.html#child_process_example_sending_server_object

    我不能保证这会提高性能,但它允许您并行处理来自不同用户的输入。我也不知道 WebSockets 是否支持这一点,但我认为是的。

    减少套接字开销

    记住这一点很重要 - 您不能将套接字对象存储在磁盘上,但您可以存储大多数其他内容。套接字对象几乎不会占用大量内存,但如果您存储有关用户的其他信息,它可能会减慢您的速度。冗余信息应存储在数据库或类似的东西提供的后端。

    原生核心

    如果您仍然遇到问题,您可以为您的聊天编写 C/C++ 原生多线程内核,并让它执行繁重的操作,例如循环通过套接字并向它们发送消息。将此核心连接到您的逻辑所在的 Node.js 服务器。也不是你可以为 Node.js 编写本机插件。

    【讨论】:

    • 非常感谢兄弟。我会再等一会儿,如果只有一个问题,我会接受你的回答。 (只是一个场景)假设像 Facebook 这样的公司这样做并且同时拥有数百万用户在线。他们所有的套接字信息都存储在同一服务器的一个数组中。那么,查找socket对象的效率如何呢?是否有类似索引数组来处理这种情况的东西?我不担心它需要的存储内存,而是搜索数组所需的时间。
    • 他们几乎不使用单个服务器来完成任务。您可以在全球范围内建立一个服务器网格,只共享他们需要的信息。此外,它们几乎不会遍历某个数组,这不是处理这个问题的方法。当客户端请求未读消息时,它们会从数据库中获取并发送给他。如果他刚刚连接,他可能仍在轮询某个数据库,因为正如我所说,他可能没有连接到同一台服务器。
    • 我想了很多,如果我被要求在节点 JS 中处理这个问题,我会运行几个进程,每个进程都处理 X 套接字。我会使用类似的算法 minecraft 用来存储块。有16x16的数据块,你首先计算块块(坐标/16。四舍五入),然后循环特定块的块。
    • 嗯.. 明白了.. 但是如果你把它分成进程,服务器仍然必须检查每个进程中的套接字,直到找到相应用户的套接字对象。这可能是一种改进,但仍然有点无效。或者可能像 Hadoop 那样做?就像向所有进程并行发送搜索请求,这使搜索更快?可能吗?
    • @vignesh 不,我说的是这样的多任务处理,其中用户 ID 包含有关他正在运行的线程的信息。考虑这个问题确实很有趣,但你会发现它没有真正的-生活应用。
    猜你喜欢
    • 2014-07-08
    • 1970-01-01
    • 2017-07-26
    • 2015-07-30
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 2020-07-04
    • 2013-05-29
    相关资源
    最近更新 更多