[ 咨询 ] 好友聊天功能如何实现

2023-07-13 10:52:50 +08:00
 NeverBelieveMe

公司项目需要增加这么一个社交的功能,网上搜了一下,基本都是 socket 的方式去实现。这种方案也比较好理解,tcp 长链之后进行消息收发。自己简单写了一下多种事件的处理,可以运行。

这里有几个问题

  1. 我是在全局变量里面保存了每一个 client ,根据 IP 来取,然后进行消息发送。用户量不大,应该不会出现数据量过大的内存问题。不过还是想问一下,有没有什么好的方案。
  2. 以前写过一个类似的东西,是 socket 用多线程做事件并发处理的,现在改用 python 的 streams ,直接使用协程方法了,想问一下,这一块还需要搞协程池或者设置协程数量吗?我看文档上没写这个。
  3. socket 是单线程,可支持的并发量能有多大?虽然用不到高并发高可用,但是想了解一下,如果说用户量很大的情况下,单台服务器无法支撑的情况下,如何升级架构?
3692 次点击
所在节点    Python
42 条回复
brader
2023-07-13 10:55:55 +08:00
其实聊天挺复杂的,越做越深入,遇到问题会越多,想省事还是直接用第三方的。如果你说体量小,想用自己的也好,你要开发出一个基本功能完善的 IM ,我预估 2 个月工期是少不了的,后续还要持续维护
opengps
2023-07-13 10:57:52 +08:00
1 ,看你 socket 的收和发缓冲区设置的是不是过大,这个地方直接决定了内存占用量
2 ,单台服务器,有些模型单机可以做到服务端承载几十万连接,实际你按照几万理解行了,因为太多连接会让故障重建的时间拉得很长,密集建立期间 cpu 也是爆满的
3 ,单台无法支撑了,那就需要合理的架构集群设计了,这不是一句话说的明白的,但其实也没那么难
me1onsoda
2023-07-13 10:58:02 +08:00
什么单不单线程,你是想说阻塞非阻塞吧?
brader
2023-07-13 11:01:01 +08:00
你说的思路差不多是对的,但你只说到了众多实现的其中一点,远远不够完善,一个 IM ,大致你要实现:绑定了所有客户端 ID 的句柄、客户端 ID 与 UID 的绑定关系、UID 与组的绑定关系、心跳检测、私聊、群聊、拉取离线消息、离线消息推送、离线消息恢复、支持多种消息类型、分布式同步信息,这只是其中一部分,还有很多其他功能要实现,我就不列举了。有个开源的 PHP 项目,实现了我说的一些基础功能,你可以借鉴他的思想,看看别人是如何设计及维护客户端列表、UID 绑定、GROUP 绑定、心跳检测等等这些东西的
https://www.workerman.net/doc/gateway-worker/
unii23i
2023-07-13 11:07:29 +08:00
我们开发说做好一个基础版至少六个月,于是我们用了第三方的,用的是腾讯 im ,感觉不是很好,收发消息有时候会错位,也不适合迭代其他功能
NeverBelieveMe
2023-07-13 11:07:37 +08:00
@brader #4 感谢提供思路
unii23i
2023-07-13 11:09:26 +08:00
我觉得完全可以用类及时通讯,隔个一分钟再发给对方什么的,也没啥影响
vaaagle
2023-07-13 11:09:41 +08:00
理论上,如果你想要建立一个聊天室,需要考虑到以下几个方面的内容:

选择协议:根据你的需求和目标,选择适合的协议。对于实现双向通信的聊天室,Socket 是一个不错的选择。通过 Socket 可以实现在客户端和服务器之间进行收发消息的功能。

中间件支撑:在协议的基础上,为了应对复杂的业务需求,你可能需要引入一些中间件来支持。这些中间件可以包括各种缓存、队列等。缓存可以用于提高系统的读取性能,队列可以用于处理消息的异步发送和接收。

开源 IM 工具:如果时间和理解有限,可以考虑使用开源的即时通讯( IM )工具来实现聊天室。这些工具已经经过了实践和稳定性验证,可以帮助你快速搭建一个简单的聊天室。你可以选择符合你需求的开源 IM 工具,并按照其文档进行配置和使用。

自己编写:如果你希望通过自己编写来磨练技术,也可以多阅读相关的技术博客,综合各方面的知识,逐步实现一个聊天室。你可以参考一些开源项目或者教程,了解聊天室的基本原理和实现方式。

需要注意的是,以上只是一些一般性的建议,具体的润色还要结合具体情况进行分析和优化。
NeverBelieveMe
2023-07-13 11:17:28 +08:00
@unii23i #7 我只需要做个功能就行,没多少用户。
NeverBelieveMe
2023-07-13 11:17:57 +08:00
@vaaagle #8 这是 GPT 的回答吗
robot1
2023-07-13 13:57:36 +08:00
这个问题逻辑性很差,而且我觉得你搞不了这个事,为什么这么说?
根本就没从业务出发去考虑技术选型,上来就是零散的技术名词,性能问题,这些都是次要的,你要先考虑业务,业务是什么?
什么场景,有没有群,消息要不要必达,要不要及时性,能不能丢,消息频率,用户数预估
wbconnie
2023-07-13 14:04:26 +08:00
对于实现社交功能的方案,使用 socket 是常见且合理的选择。不过,如果你希望尝试其他方案,可以考虑使用现有的开源社交网络框架,如 Django 社交网络插件或 Open Source Social Network (OSSN)等。

关于保存每个客户端的全局变量,根据 IP 来取,这种方式对于用户量不大的情况而言是可行的。如果确保数据量不会过大,且内存占用量在可接受范围内,那么这个方案是没有问题的。但请确保在并发访问时进行线程/协程安全的访问,以避免数据竞争的问题。

关于协程的处理,如果你使用的是 Python 的异步流( streams )框架(如 asyncio ),它会自动管理协程池和协程数量。你无需手动创建协程池或设置协程数量,框架会根据系统资源和并发情况自动进行调整。

关于 Socket 的并发处理能力,实际上取决于服务器的性能,特别是 CPU 和内存的能力。对于普通的聊天应用来说,Socket 的并发处理能力很高,可以同时处理数百到数千个连接。但当用户量大到单台服务器无法支撑时,可以考虑以下升级架构的方案:

1. 横向扩展:通过增加更多的服务器实例并将负载均衡器放置在服务器前面,将流量均匀地分发到多个服务器上,以提高整个系统的并发处理能力。

2. 分布式架构:将系统拆分成多个逻辑模块,每个模块分别部署在不同的服务器上,通过消息队列或分布式数据库进行通信和数据同步。这样可以将负载分散到多个服务器上,提高整个系统的可伸缩性和性能。

综上所述,根据你的需求和用户量的大小,选择合适的方案并进行相应的架构升级是很重要的。
Baloneo
2023-07-13 14:12:12 +08:00
emqx mqtt?
godleon
2023-07-13 14:24:11 +08:00
如果只文字聊天,自己服务端跟客户端建 socket 就可以满足了, 如果要求发语音消息跟图片 视频聊天 语音聊天,建议还是上第三方,因为自己实现需要流服务器,相对比较麻烦些,如果是 go 当我没说 [手动狗头!]
vaaagle
2023-07-13 14:26:58 +08:00
这是我的回答,gpt 润色了一下 ahhhh~
NeverBelieveMe
2023-07-13 14:30:45 +08:00
@Baloneo #13 之前就是在用 mqtt 搞聊天,不过现在想换条路子走走看
coderxy
2023-07-13 14:32:58 +08:00
我们写的第一个 im ,用了将近 2-3 个月才线上稳定,确实有很多坑,如果原来没接触过,建议先买第三方。
NeverBelieveMe
2023-07-13 14:33:29 +08:00
@godleon #14 只是简单文字聊天
coderxy
2023-07-13 14:38:14 +08:00
@godleon 发语音跟图片都是上传到 oss ,然后发送对应类型的 im 消息。 语音、视频那是 RTC 的范畴了,跟 IM 不是一个东西
wonderblank
2023-07-13 14:50:51 +08:00
mqtt 应该就行了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/956389

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX