公司项目需要增加这么一个社交的功能,网上搜了一下,基本都是 socket 的方式去实现。这种方案也比较好理解,tcp 长链之后进行消息收发。自己简单写了一下多种事件的处理,可以运行。
这里有几个问题
1 brader 2023-07-13 10:55:55 +08:00 其实聊天挺复杂的,越做越深入,遇到问题会越多,想省事还是直接用第三方的。如果你说体量小,想用自己的也好,你要开发出一个基本功能完善的 IM ,我预估 2 个月工期是少不了的,后续还要持续维护 |
![]() | 2 opengps 2023-07-13 10:57:52 +08:00 ![]() 1 ,看你 socket 的收和发缓冲区设置的是不是过大,这个地方直接决定了内存占用量 2 ,单台服务器,有些模型单机可以做到服务端承载几十万连接,实际你按照几万理解行了,因为太多连接会让故障重建的时间拉得很长,密集建立期间 cpu 也是爆满的 3 ,单台无法支撑了,那就需要合理的架构集群设计了,这不是一句话说的明白的,但其实也没那么难 |
![]() | 3 me1onsoda 2023-07-13 10:58:02 +08:00 什么单不单线程,你是想说阻塞非阻塞吧? |
4 brader 2023-07-13 11:01:01 +08:00 ![]() 你说的思路差不多是对的,但你只说到了众多实现的其中一点,远远不够完善,一个 IM ,大致你要实现:绑定了所有客户端 ID 的句柄、客户端 ID 与 UID 的绑定关系、UID 与组的绑定关系、心跳检测、私聊、群聊、拉取离线消息、离线消息推送、离线消息恢复、支持多种消息类型、分布式同步信息,这只是其中一部分,还有很多其他功能要实现,我就不列举了。有个开源的 PHP 项目,实现了我说的一些基础功能,你可以借鉴他的思想,看看别人是如何设计及维护客户端列表、UID 绑定、GROUP 绑定、心跳检测等等这些东西的 https://www.workerman.net/doc/gateway-worker/ |
![]() | 5 unii23i 2023-07-13 11:07:29 +08:00 我们开发说做好一个基础版至少六个月,于是我们用了第三方的,用的是腾讯 im ,感觉不是很好,收发消息有时候会错位,也不适合迭代其他功能 |
![]() | 6 NeverBelieveMe OP @brader #4 感谢提供思路 |
![]() | 7 unii23i 2023-07-13 11:09:26 +08:00 我觉得完全可以用类及时通讯,隔个一分钟再发给对方什么的,也没啥影响 |
![]() | 8 8zU02dFZkHXS6230 2023-07-13 11:09:41 +08:00 理论上,如果你想要建立一个聊天室,需要考虑到以下几个方面的内容: 选择协议:根据你的需求和目标,选择适合的协议。对于实现双向通信的聊天室,Socket 是一个不错的选择。通过 Socket 可以实现在客户端和服务器之间进行收发消息的功能。 中间件支撑:在协议的基础上,为了应对复杂的业务需求,你可能需要引入一些中间件来支持。这些中间件可以包括各种缓存、队列等。缓存可以用于提高系统的读取性能,队列可以用于处理消息的异步发送和接收。 开源 IM 工具:如果时间和理解有限,可以考虑使用开源的即时通讯( IM )工具来实现聊天室。这些工具已经经过了实践和稳定性验证,可以帮助你快速搭建一个简单的聊天室。你可以选择符合你需求的开源 IM 工具,并按照其文档进行配置和使用。 自己编写:如果你希望通过自己编写来磨练技术,也可以多阅读相关的技术博客,综合各方面的知识,逐步实现一个聊天室。你可以参考一些开源项目或者教程,了解聊天室的基本原理和实现方式。 需要注意的是,以上只是一些一般性的建议,具体的润色还要结合具体情况进行分析和优化。 |
![]() | 9 NeverBelieveMe OP @unii23i #7 我只需要做个功能就行,没多少用户。 |
![]() | 10 NeverBelieveMe OP @vaaagle #8 这是 GPT 的回答吗 |
11 robot1 2023-07-13 13:57:36 +08:00 这个问题逻辑性很差,而且我觉得你搞不了这个事,为什么这么说? 根本就没从业务出发去考虑技术选型,上来就是零散的技术名词,性能问题,这些都是次要的,你要先考虑业务,业务是什么? 什么场景,有没有群,消息要不要必达,要不要及时性,能不能丢,消息频率,用户数预估 |
12 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. 分布式架构:将系统拆分成多个逻辑模块,每个模块分别部署在不同的服务器上,通过消息队列或分布式数据库进行通信和数据同步。这样可以将负载分散到多个服务器上,提高整个系统的可伸缩性和性能。 综上所述,根据你的需求和用户量的大小,选择合适的方案并进行相应的架构升级是很重要的。 |
13 Baloneo 2023-07-13 14:12:12 +08:00 emqx mqtt? |
14 godleon 2023-07-13 14:24:11 +08:00 如果只文字聊天,自己服务端跟客户端建 socket 就可以满足了, 如果要求发语音消息跟图片 视频聊天 语音聊天,建议还是上第三方,因为自己实现需要流服务器,相对比较麻烦些,如果是 go 当我没说 [手动狗头!] |
![]() | 15 8zU02dFZkHXS6230 2023-07-13 14:26:58 +08:00 这是我的回答,gpt 润色了一下 ahhhh~ |
![]() | 16 NeverBelieveMe OP @Baloneo #13 之前就是在用 mqtt 搞聊天,不过现在想换条路子走走看 |
17 coderxy 2023-07-13 14:32:58 +08:00 我们写的第一个 im ,用了将近 2-3 个月才线上稳定,确实有很多坑,如果原来没接触过,建议先买第三方。 |
![]() | 18 NeverBelieveMe OP @godleon #14 只是简单文字聊天 |
19 coderxy 2023-07-13 14:38:14 +08:00 @godleon 发语音跟图片都是上传到 oss ,然后发送对应类型的 im 消息。 语音、视频那是 RTC 的范畴了,跟 IM 不是一个东西 |
20 wonderblank 2023-07-13 14:50:51 +08:00 mqtt 应该就行了 |
![]() | 21 npe 2023-07-13 14:53:51 +08:00 Websocket / MQTT |
22 assiadamo 2023-07-13 15:05:47 +08:00 社交做下去就要各种审核屏蔽字,准备好了吗 |
![]() | 23 darkengine 2023-07-13 15:06:54 +08:00 集成个第三方吧,这玩意儿是个无底洞 |
24 jiaoery 2023-07-13 15:27:42 +08:00 ![]() 能用第三方尽量用第三方,分之前公司就搞过自己的聊天系统,分享一下自己的踩坑之旅(各位大佬不喜勿喷)后端用的方案是 socket 做及时推送,http 做同步的方式;一开始只有简单的 1v1 的服务,当时就搞了个 id 对 id 的方式来搞;后面又搞群聊,如果群里只有两个人,容易误发到之前 id 对 id 的情况下,而且只要有新用户加入群聊,又要迁移数据,就搞了一个 |
![]() | 25 so1n 2023-07-13 15:32:00 +08:00 有对接前端的话,可以考虑用下 socketio ,不然就 websocket |
26 jiaoery 2023-07-13 15:34:28 +08:00 @jiaoery conversationId ,然而还有个麻烦,就是如果群聊所有人都退出,需要回收资源;这就必须搞一个定时任务来检查所有的 conversation ;这个解决了;后面业务从国外转入国内,又出现国内某些厂商杀后台的情况,本身及时推送就是在一个 service 里,然后各种保活的方案,适配国内的各个 OEM 又是一地鸡毛,当时团队里搞这个就压了一半的人,痛苦不行;而且上面的问题还是我遇到过的,没遇到的估计更多;要问为什么自己搞,也是当时用第三方的,如个推,信鸽,友盟等上 Google Play 由于内部带广告 API 给扫出来,直接给下架了;甚至当时还给个推写过投诉邮件 |
27 lx271896700 2023-07-13 16:03:17 +08:00 能用第三方,就用第三方。我曾在两个公司负责 im 项目,开发周期都在 1 年左右,两家公司都是辛辛苦苦开发了一年,最后兜兜转转,都回到了第三方。第三方应该也有按量计费的,你可以找找看。 |
28 coderxy 2023-07-13 16:24:53 +08:00 @lx271896700 兄弟,不至于吧? 开发了一年最后还转回第三方了? 你们最后是啥问题解决不了? 说出来让大家涨涨见识。 |
![]() | 29 NeverBelieveMe OP @assiadamo #22 接入阿里云的审核的。 |
![]() | 30 NeverBelieveMe OP @jiaoery #24 感谢分享经验 |
![]() | 31 LindsayZhou 2023-07-13 16:50:23 +08:00 我觉得你们在讨论怎么重新造 irc (小声) 只是不能发图片语音,irc 服务端应该有不少开源实现的,找个来改改? irc 也能分布式横向扩展 ( rfc2813 ),不过许多服务端并没有实现。 |
32 lx271896700 2023-07-13 17:04:19 +08:00 @coderxy #28 第一家公司是比较奇葩,公司只有四五个人,一个 iOS+一个安卓+一个后台,用 websocket 搞了一年,app 没什么用户,ios 和安卓都跑了,app 没有人维护,就换了第三方的 im 。第二家公司,也用 websocket 搞了几个月,后来换了小米的 MIMC ,因为 MIMC 免费,初用没发现什么问题,但后来我们使用量大了之后,qps 受限,消息积压严重,只好又换成腾讯 IM(旗舰版),好在之前写的 UI 界面可以继续使用,所以改动不算太大。 |
33 coderxy 2023-07-13 17:10:52 +08:00 @lx271896700 原来如此, 第三方 im 在 app 早期的时候肯定是够用的,量大了费用就上来了,这个阶段再自研也不迟。 |
![]() | 34 NeverBelieveMe OP @lx271896700 #27 我也想用第三方,不过客户不愿意掏钱 |
35 chong3397 2023-07-13 18:55:43 +08:00 |
36 linnana 2023-07-13 19:16:39 +08:00 1.用 ip 存映射关系可能不是一个好的选择?可以考虑用户的 uid 存映射关系,比如以 uid 映射 connected-client , 也方便后继要做多设备同步等等。 2.网络和 IO 等层面的东西用网络编程库和框架来替代就可以了,比如我们用的 Netty ,Python 不太熟但应该也有类似的东西。 3.单台服务器无法支撑的情况下,可以前置一个 im-route 模块用某种规则路由(往往取决于业务需要)到不同的 im-server 上,同时所有当消息需要做跨 im-server 路由时,需要全局的在线记录表来找到一个用户在哪个 im-server 实例上。这时候需要一个全局在线记录映射等等。扩展可能还会有 login/broker/store/sensitive-censor 等子模块拆分。 |
![]() | 37 tyzandhr 2023-07-13 21:27:52 +08:00 我很好奇,为什么发在 python 标签 |
38 fluyy 2023-07-13 21:50:51 +08:00 via iPhone 我觉得直接用第三方的比较好。单纯的看你这个问题,第一个问题最好最好以用户 id 来存 client , |
39 fluyy 2023-07-13 21:53:22 +08:00 via iPhone 第二个问题不太清楚了。第三个规模扩大了,那就要有多台机器。简单的可以再搭一个接入层,然后根据 userid hash 到后端业务机器。 |
40 kuituosi 2023-07-14 09:47:40 +08:00 via Android im 主要分两种类型,是否支持离线消息。支持离线消息复杂很多,其中又分服务器是否集群,毕竟单点故障会影响用户体验。如果只支持在线消息这个很简单。如果不支持集群的离线消息,难度也不大。如果支持离线消息并且服务器集群,那难度相当大。至于 python 单机支持的连接数其实问题不太大,比较聊天很多时候处理逻辑不复杂,大不了多进程就能解决 |
![]() | 41 xiaoshan5733 2023-07-14 15:59:32 +08:00 感觉悟空 IM ( https://githubim.com/) 挺适合 OP 的,一键部署,业务分离,可以试试 |
![]() | 42 qbmiller 2023-07-14 16:03:10 +08:00 花钱买服务,接入云信。 越做越复杂, 我们 5w dau 每月几万块钱,但自己做,后端+客户端+推送+服务器.... 那一摊子,每月 2 个人成本打不住.... 没多少人的外包项目,可以用 openim 算是全套的了。 |