V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
godleon
V2EX  ›  Java

话说要是自己实现一套 IM 的功能难度大吗?

  •  
  •   godleon · 2022-05-25 09:48:46 +08:00 · 7760 次点击
    这是一个创建于 946 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前言

    想自己做一个 IM 的包实现起来难度大吗?
    
    MQTT 协议,java ,netty+socket
    

    问题

    特别想问一下,就是这个"语音消息" 不是语音通话,一条条的语音消息,这个是怎么实现的呀?还有像聊天记录的存储格式了,有没有热心 v 友能给一些思路或者一些开源的参考~ 
    

    ps: 语音消息,问了一个大佬,他说发语音消息的时候,先录音成.mp3 文件到本地,然后发送到另一端,另一端接收播放这个.mp3 ,这....

    第 1 条附言  ·  2022-05-25 15:57:11 +08:00

    帖子的标题确实是我范围给的太大了!其实我只是想讨论一些IM功能的实现方式;

    一套完整的IM的难度确实是取决于你想要实现功能的多少,承载多少用户量;

    但是后者对我来说目前可以是不考虑的,如果功能都实现不了其他的就毫无意义~

    所以只是想讨论一个功能的多种实现方式吧;

    举个例子,假如要做一个APP,功能就对标实物对讲机,进入APP的所有用户,可以选择频道,在一个频道内,某一个用户发语音,频道内所有人都能听到而且是实时的;

    上面我只是举例,IM的功能是很丰富的,但是你自己的产品的核心功能是你自己来决定的,可能我要做的SDK最主要的就是语音的实现,上面的需求会有很多种实现方式,但是作为核心的话要考虑低开销,高实时的性能问题,像文本 图片等功能在这里可能起到一个可有可无的需求;

    55 条回复    2022-06-01 15:32:59 +08:00
    sadfQED2
        1
    sadfQED2  
       2022-05-25 09:55:03 +08:00 via Android
    大学 cs 专业学生,应该绝大多数人都写过 im 聊天软件吧
    XiLingHost
        2
    XiLingHost  
       2022-05-25 09:55:12 +08:00
    你可以把声音用 opus 之类的编码器进行编码,然后传二进制报文过去
    murmur
        3
    murmur  
       2022-05-25 09:57:17 +08:00
    作业级别的语音消息真的可以这么做,以前没有 4g 网的时候要各种考虑压缩,现在的网速发个 mp3 问题也不大
    cutepeer
        4
    cutepeer  
       2022-05-25 09:59:54 +08:00
    一般都用云服务了啦,接入 sdk ,消息云同步啥的都替你做好,云平台还能加审核过滤功能,你需要做的只是维护用户间的关系。全部自己实现的话就要维护太多东西了
    pubby
        5
    pubby  
       2022-05-25 10:02:20 +08:00
    “ps: 语音消息,问了一个大佬,他说发语音消息的时候,先录音成.mp3 文件到本地,然后发送到另一端,另一端接收播放这个.mp3 ,这....”

    难道不是这样吗?
    当然发送到另一端的可以是 mp3 文件,也可以是把文件存服务器,只发个播放地址过去。
    godleon
        6
    godleon  
    OP
       2022-05-25 10:04:38 +08:00
    @cutepeer 就是要自己做 SDK
    TimPeake
        7
    TimPeake  
       2022-05-25 10:06:28 +08:00   ❤️ 1
    忽然想起了 ‘像寻’公众号事件 , “”程序员都知道, 自己实现一套 IM 至少 2 个月以上“”
    godleon
        8
    godleon  
    OP
       2022-05-25 10:11:26 +08:00
    @murmur 不是作业级别的语音有什么传输更好一点呢
    darkengine
        9
    darkengine  
       2022-05-25 10:11:29 +08:00
    语音消息就是录制好的 mp3 上传到服务器,发链接给对方,这个思路没毛病啊
    godleon
        10
    godleon  
    OP
       2022-05-25 10:13:49 +08:00
    @pubby
    @darkengine

    我没说有毛病,只是在想优质的 IM 做的这个功能,也是.mp3 文件嘛,就像 2 楼说的是不是 可以编辑为 2 进制传输,这效率不是高太多了
    yukiww233
        11
    yukiww233  
       2022-05-25 10:17:30 +08:00   ❤️ 13
    @godleon #10 有没有一种可能,mp3 也是一种高效率编码二进制文件呢
    lakehylia
        12
    lakehylia  
       2022-05-25 10:17:32 +08:00
    语音消息可以用电信的标准,一般用 AMR 。
    lizy0329
        13
    lizy0329  
       2022-05-25 10:20:28 +08:00
    0-1 难度不大 1-100 难度非常大
    janus77
        14
    janus77  
       2022-05-25 10:21:09 +08:00
    这种宽泛的问题肯定看实际情况啊,毕业设计和商业产品不一样,服务端和客户端不一样,包含功能的多少也可以有变化(比如撤回、引用回复、发语音、表情包、视频、文件等)
    你什么都没说我只能当成 “找外包 1000 做一个微信” 来看待了
    codehz
        15
    codehz  
       2022-05-25 10:22:01 +08:00
    语音消息这么做也没啥问题,不过一般来说会有专门的格式编码——不需要多余的元数据,压缩算法专门针对(非即时的)语音场景
    (另外二进制比文本效率高这说法槽点多到不知道从哪里开始说比较好((((
    darkengine
        16
    darkengine  
       2022-05-25 10:22:04 +08:00
    @godleon

    就像 2 楼说的是不是 可以编辑为 2 进制传输,这效率不是高太多了

    -------------

    不要一开始就考虑优化。而且 2 楼提到的 opus 一般用在实时语音领域,需求里一条条的语音消息,完全没必要上这个增加复杂度。
    godleon
        17
    godleon  
    OP
       2022-05-25 10:22:25 +08:00
    @lizy0329 认同,只实现功能应该问题不大,但是主要是要看你的期望是做到什么样,这就是无上线的了。
    XiLingHost
        18
    XiLingHost  
       2022-05-25 10:22:44 +08:00
    @yukiww233 mp3 的问题不是在于授权协议吗
    zsdroid
        19
    zsdroid  
       2022-05-25 10:25:17 +08:00
    语音不用 mp3 ,用 amr ,体积小。语音消息有损压缩也没事。
    还有长链接存储问题:
    长链接无法存到数据库 /redis 中。那服务器 1 的用户给服务器 2 的用户发送信息,1 是找不到 2 下用户的 channel ,故无法直接发送信息。
    bruce0
        20
    bruce0  
       2022-05-25 10:38:18 +08:00
    我的理解啊 做个能用的不难, 但是做个好用的 就是没有上限的了, 也就是挺难的
    unnamedhao
        21
    unnamedhao  
       2022-05-25 10:45:41 +08:00
    看承载量,10 个人用跟 10 亿人用的难度差别还是很大的
    lyy16384
        22
    lyy16384  
       2022-05-25 10:58:05 +08:00
    https://github.com/OpenIMSDK
    用开源的吧,感觉完整的 IM 不是一个人就能搞定的项目
    lonewolfakela
        23
    lonewolfakela  
       2022-05-25 11:03:18 +08:00
    @XiLingHost #18 mp3 的专利不是已经过期了么
    tanxnative
        24
    tanxnative  
       2022-05-25 11:03:54 +08:00
    可以看看 https://github.com/stream-stack/store-operator 云原生消息中间件
    基于此实现 IM 很简单
    tigerstudent
        25
    tigerstudent  
       2022-05-25 11:04:39 +08:00
    opus 调用不麻烦,能压缩到原音频的十分之一
    keppelfei
        26
    keppelfei  
       2022-05-25 11:42:46 +08:00
    实现一套不难,最最简单的 websocket 就能搞一套,难得是集群扩展承载力。
    libook
        27
    libook  
       2022-05-25 11:49:05 +08:00
    可以把语音数据部分和传输部分解耦,不管啥格式的数据都可以在传输通道里走,这样你可以先上 MVP 方案用现成的编码格式,比如 mp3 ,等核心部分都搞定了,再看看是不是要替换语音编码。

    除非你现在已经把 IM 核心功能都搞定了,就剩语音了。
    wxlwsy
        28
    wxlwsy  
       2022-05-25 11:57:55 +08:00
    计算机上,除开算法问题, 其他问题不难, 难的是如何落地。
    y830CAa5nink4rUQ
        29
    y830CAa5nink4rUQ  
       2022-05-25 13:06:50 +08:00   ❤️ 1
    做一个能简单互相发消息的 IM 系统不难,假设这个难度是 1 。

    在这个基础上做出一个不但要能发消息,还要用起来比较顺手的,已经非常困难了,非常多的细节需要考虑。关于这个我就举个例子:发送者可以自由发送五花八门各种格式的视频,接受者要能直接点看。这个别看就一句话,实际上做起来非常非常非常困难,基本上你需要集成一整套视频编码、解码、播放系统进去。这一步难度大约是 100 。

    然后再在用起来比较顺手的基础上,做一套能支持海量用户的系统,这个就不是普通公司能完成的事情了,这个难度大约是 10000 。
    markgor
        30
    markgor  
       2022-05-25 13:26:00 +08:00
    可是一套 IM 不止是发语音。
    beimenjun
        31
    beimenjun  
       2022-05-25 13:38:13 +08:00
    做出来的 IM 是给一个人用的还是给一百万人用的,不是同一个级别的难度。

    玩具你随便弄弄,弄成点对点都可以说是 IM 吧。

    正儿八经的 IM ,服务端要考虑服务的拓展性、性能、灾备、安全性、合规。

    落到移动客户端,这个问题可能还涉及客户端的耗电、内存使用、流量使用、数据状态的同步、各类错误处理。
    xiangyuecn
        32
    xiangyuecn  
       2022-05-25 13:53:26 +08:00
    别问,问就是 上传+下载
    oppoic
        33
    oppoic  
       2022-05-25 14:05:47 +08:00
    关键问题是满足多大用户量。
    如果只是几个人发发消息,用 ajax 轮询服务端也做了是吧
    imndx
        34
    imndx  
       2022-05-25 14:10:33 +08:00
    @xiangyuecn 正解。
    yufeng0681
        35
    yufeng0681  
       2022-05-25 15:00:42 +08:00
    一个 IM 系统的讨论,偏离到语音消息的传送细节了。
    有空去看看 GSMA 国际规范 RCS ,里面讲述的内容大于 IM , 但是能更好的帮助你了解 IM 系统
    jstony
        36
    jstony  
       2022-05-25 16:21:55 +08:00
    这么说吧,当年学校机房里写了个 im ,可以同学之间聊天,类似飞鸽传书,同一年,qq 第一版面市。
    poembre
        37
    poembre  
       2022-05-25 18:14:12 +08:00
    - 前些天, 用 B 站 毛剑大佬开源的 goim 改了一个 客服聊天

    https://github.com/poembro/goim-demo
    pengtdyd
        38
    pengtdyd  
       2022-05-25 18:16:10 +08:00
    答:自己写个 IM 难度几乎为 0 ,重点是有人用。
    byron
        39
    byron  
       2022-05-25 18:54:33 +08:00
    dudubaba
        40
    dudubaba  
       2022-05-25 19:06:13 +08:00
    不难啊,就像现有的卖 IM 服务的企业根本不是卖技术本身,而是卖数据存储的,流量带宽大了贼贵。
    littlewing
        41
    littlewing  
       2022-05-25 19:13:58 +08:00
    功能做出来不难,难的是优化和用户体验,还有承载用户量
    stillyu
        42
    stillyu  
       2022-05-25 21:51:15 +08:00
    感觉会这么问的,不像是程序员

    IM 可能没做过,但商城每个工作了的程序员都做过吧?

    自己做的商城和淘宝比,工作量和难度不都心里有数了吗?

    ps:商品详情,问了一个大佬,他说编辑商品详情的时候,先编辑成.doc 文件存在本地,然后在商品详情编辑框粘贴上去,页面显示这个内容,这...
    firechat
        43
    firechat  
       2022-05-25 23:06:12 +08:00
    以我的经验给你几点建议吧
    1. 格式用 amr ,amr 的好处是对人声处理的特别好,压缩比特别高,基本上每秒小于 1KB 。
    2. 发送语音有 2 个种办法,一种是上传到一个服务器,把链接发送给对方,对方播放再下载;另外一种是直接放到消息体内直接发送给对方。如果是对讲语音,用第二种方式。
    3. 对接的话不需要考虑存储,对方不在就直接丢掉。如果只有对讲可以不用考虑离线消息和消息存储。当然如果有其它类型的消息则必须实现了。
    4. 不要从 0 开始写,现在有开源的 MQTT 服务和客户端,一个频道就是一个 topic 就行,再加上抢麦的功能,这种网上有很多抢红包的例子,比较类似。
    5. 要逐步实现,不要贪大求全,上来就高并发微服务。先功能再优化。

    另外感觉你问得太笼统了,如果做好一个通用型的 IM 是非常困难的,你基本上在这里得不到答案。你可以详细说一下问题和需求。
    nicevar
        44
    nicevar  
       2022-05-25 23:35:25 +08:00
    有一段时间做 IM 的扎堆,基本上都挂了,从头到尾自己做意义不大,直接上 XMPP 之类的就行了
    XiLingHost
        45
    XiLingHost  
       2022-05-26 00:14:18 +08:00
    建议做一个用户体验好的 xmpp 客户端
    mingl0280
        46
    mingl0280  
       2022-05-26 00:52:33 +08:00
    大,而且大到坑爹。
    你举例的那个操作,要坑死你
    1. 网络不好的带宽有限,移动网络的容易不在网,丢包网络的切换的时候丢了几个包,怎么办?实时性做到哪个程度?没听到的能不能回溯?
    2. 一个频道要承载多少人?网络协议走可靠的还是不可靠的?服务器要预备多少带宽?有没有 fallback 到 p2p 功能?如果 fallback 怎么打洞?
    3. 客户端要多少个平台? Android 底下的设备要适配多少? Apple 的呢?桌面的呢?
    4. 你这个系统准备有多少容灾,是不是个人部署,要不要考虑部署的合规性?
    还有具体的技术细节一箩筐……
    documentzhangx66
        47
    documentzhangx66  
       2022-05-26 07:04:50 +08:00
    1.作业级别的一点都不难,语音视频什么的无脑开源协议,甚至 mp4 、rtmp 等等。

    2.如果要自己设计音频视频协议,那就麻烦很多,需要从数学原理开始进行优化,不然未压缩的 raw 音频与视频数据量,尺寸会大到离谱。

    3.最麻烦的是给所有人用的量级,这就不是技术问题了。你需要有足够的资金,拿来买带宽、服务器、甚至机房。
    cnbattle
        48
    cnbattle  
       2022-05-26 08:12:01 +08:00 via Android
    不考虑语音视频通话,用户量,

    用 mqtt 两三天,去年搞过,

    没搞过语音视频场景,跟着上面大佬学习一波
    GeruzoniAnsasu
        49
    GeruzoniAnsasu  
       2022-05-26 08:53:20 +08:00
    有没有一种可能,不需要把文件写到外存上,录在内存里直接发出去就可以了
    bl4ckoooooH4t
        50
    bl4ckoooooH4t  
       2022-05-26 09:17:25 +08:00
    市面上挺多 IM 都是把音频录好,上传到云存储,然后发一个 音频类型的消息,里面带了音频文件的 URL 。 融云、云信、腾讯都有 SDK ,可以参考看看
    Lambert2022
        51
    Lambert2022  
       2022-05-26 09:19:25 +08:00
    可以直接集成 firebase 来实现
    sparky
        52
    sparky  
       2022-05-26 09:34:28 +08:00
    WebRTC ?
    EvanLuo42
        53
    EvanLuo42  
       2022-05-26 16:29:50 +08:00
    一直挺想写 IM ,最近学了 Rust ,想拿 Rust 试试。
    mrjnamei
        54
    mrjnamei  
       2022-05-26 17:21:29 +08:00
    文件信息肯定是传播放地址啊,把文件上传到云存储,把地址当做语音消息传过去,另一端直接播放这个在线 MP3
    superchrisliu
        55
    superchrisliu  
       2022-06-01 15:32:59 +08:00
    @documentzhangx66 自己设计音视频协议。。光这一项你一年都做不完,就算是生产环境 rtmp 也能用
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2857 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 14:57 · PVG 22:57 · LAX 06:57 · JFK 09:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.