V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
wewin
V2EX  ›  Go 编程语言

Golang 实现的高并发聊天程序

  •  
  •   wewin · 2019-06-15 17:34:22 +08:00 · 8928 次点击
    这是一个创建于 2017 天前的主题,其中的信息可能已经有所发展或是发生改变。

    献上代码,聊表敬意

    https://github.com/ItsWewin/go-chat

    目前功能较少,欢迎 issue 中提你想要的功能,issue 中要求的功能,优先添加。欢迎吐槽或 star

    项目简介

    这是使用 Golang 网络编程实现的一个多人在线聊天程序,使用 goroutine 达到高并发的效果,使用 redis 来保存用户的注册信息

    项目由服务端和客户端两部分组成,服务端和客户端代码基本独立,server 目录下是服务端代码,client 目录下是客户端代码,commen 目录下的包由服务端和客户端共同使用

    项目目录结构如下:

    .
    ├── README.md
    ├── client // 客户端代码
    │   ├── logger // 自定义的日志打印器
    │   │   └── logger.go
    │   ├── main.go // 主函数
    │   ├── model // model 层
    │   │   └── user.go
    │   ├── process // 处理与服务器端的连接,收发消息
    │   │   ├── messageProcess.go
    │   │   ├── serverProcess.go
    │   │   └── userProcess.go
    │   └── utils
    │       └── utils.go
    ├── commen // 客户端和服务端公用代码,主要用来定义客户端和服务端之间通信约定的消息
    │   └── message
    │       └── message.go
    └── server // 服务端代码
        ├── main // 主函数
        │   ├── main.go
        │   └── redis.go
        ├── model // model 层
        │   ├── clientConn.go
        │   ├── error.go
        │   ├── user.go
        │   └── userDao.go
        ├── process // 处理与客户端的连接,收发消息
        │   ├── groupMessageProcess.go // 处理群消息
        │   ├── onlineInfoProcess.go // 显示在线用户
        │   ├── pointToPointMessageProcess.go // 处理点对点聊天消息
        │   ├── processor.go // 消息处理器入口
        │   └── userProcess.go // 处理和用户登陆注册相关消息
        └── utils 
            └── utils.go
    

    本地运行本项目(Unix 系统下)

    下载项目

    下载项目到本地的 GOPATH 目录下(后面会提供 go get 的方式以方便使用),由于这是 Golang 项目,所以需要你本地有 Golang 的运行环境

    cd ${GOPATH}/src
    git clone [email protected]:ItsWewin/go-chat.git
    

    编译和运行

    编译并运行服务端代码

    go build -o server go-chat/server/main
    ./server
    

    编译并运行客户端代码

    go build -o server go-chat/server/main
    ./server
    

    这样就大功告成,你就可以在本地体验本项目了( ps:你要是不想用微信或者 QQ 聊天可以尝试下把程度搭建在自己的服务器上,喊上你的道友们用这个软件来聊天 [手动补个捂脸的表情包] )

    项目概况

    项目目前实现了如下功能:

    1. 用户注册、登陆
    2. 显示所有在线用户列表
    3. 发送群消息(目前是发送给在线的所有用户)
    4. 私聊某一个用户
    5. 按照消息的类型(info, notice, warn, error, success) 使用不同的颜色打印消息( Unix 和 window 均支持)
    6. 其他的有空再继续扩展... (欢迎提 issue,issue 提到的优先实现)

    项目效果图

    注册

    sign-up

    登陆

    sign-in

    显示在线用户列表

    online-user-list

    群聊

    group-message-1.png group-message-2.png

    私聊

    point-to-point.png point-to-point2.png

    42 条回复    2019-06-17 10:49:22 +08:00
    wewin
        1
    wewin  
    OP
       2019-06-15 17:36:15 +08:00
    欢迎道友们 Issue 或者 star
    sunny352787
        2
    sunny352787  
       2019-06-15 17:39:28 +08:00
    功能好说,性能呢?测试加一下?
    hyyou2010
        3
    hyyou2010  
       2019-06-15 17:41:06 +08:00
    不错,可以写一下 roadmap,如果要继续完善的话
    wewin
        4
    wewin  
    OP
       2019-06-15 17:43:39 +08:00
    @sunny352787 关键部分都使用了 goroutine 并发效果应该是不会差,但是程序员不能说 “应该”(哈哈哈),测完后再来回复你。
    wewin
        5
    wewin  
    OP
       2019-06-15 17:45:27 +08:00
    @hyyou2010 好建议,我找空写下
    sunny352787
        6
    sunny352787  
       2019-06-15 17:49:24 +08:00   ❤️ 1
    看了一眼代码,强迫症又犯了...拼写错误改改? buf[:4]和 buf[0:4]没区别,用一种可好? recover 最好处理一下,不然一个 coroutine 挂了整个进程就废了,直接用 binary.Read 比这样自己算简单多了,消息缓冲如果只开 10240 的话,消息长度给个 int16 是不是更好还更安全?
    wewin
        7
    wewin  
    OP
       2019-06-15 17:59:46 +08:00
    @sunny352787 感谢,给 10 个金豆聊表敬意,提到的问题会解决。
    sunny352787
        8
    sunny352787  
       2019-06-15 18:04:43 +08:00
    @wewin 话说,你要是想再进化一些或者兼容性更大些,websocket 了解一下?回头接个 h5 前端聊天美滋滋~
    wangsongyan
        9
    wangsongyan  
       2019-06-15 18:11:18 +08:00 via iPhone
    commen,看着膈应
    luosuosile
        10
    luosuosile  
       2019-06-15 18:18:49 +08:00
    我刚好在学习 go,给你个 star
    wewin
        11
    wewin  
    OP
       2019-06-15 18:40:11 +08:00
    @sunny352787 感谢建议,等功能完善差不多再考虑吧
    wewin
        12
    wewin  
    OP
       2019-06-15 18:40:41 +08:00
    @wangsongyan 改了,凄惨的拼写
    wewin
        13
    wewin  
    OP
       2019-06-15 18:41:05 +08:00
    @wewin 谢谢!
    acehow
        14
    acehow  
       2019-06-15 19:18:40 +08:00 via Android
    4 exist 存在即合理
    sdtfll
        15
    sdtfll  
       2019-06-15 20:41:59 +08:00 via Android
    commen
    common
    ?????
    lzynb
        16
    lzynb  
       2019-06-15 21:54:55 +08:00
    性能测试呢,用数据说话
    wewin
        17
    wewin  
    OP
       2019-06-16 01:23:58 +08:00
    @sdtfll
    @acehow 可怕的拼写。
    wewin
        18
    wewin  
    OP
       2019-06-16 01:24:17 +08:00
    @lzynb 后面会补上的
    blless
        19
    blless  
       2019-06-16 03:41:40 +08:00 via Android   ❤️ 3
    学生作业般的即视感
    littlewing
        20
    littlewing  
       2019-06-16 04:02:53 +08:00 via Android
    高并发是多少并发?没测试数据就说什么高并发
    hhyvs111
        21
    hhyvs111  
       2019-06-16 06:08:52 +08:00 via iPhone
    客户端服务端一样的编译命令?话说楼主大几了?
    hhyvs111
        22
    hhyvs111  
       2019-06-16 06:14:53 +08:00 via iPhone
    看了下代码,基本上就是一个 java 项目改成 go,然后仅仅用了协程而已
    lychnis
        23
    lychnis  
       2019-06-16 07:11:07 +08:00 via Android
    命令行的聊天真的能用嘛。。。??
    Cbdy
        24
    Cbdy  
       2019-06-16 07:34:59 +08:00 via Android
    @sunny352787 go 语言默认高并发
    kiwier
        25
    kiwier  
       2019-06-16 08:15:18 +08:00
    这就是老韩的那个 go 聊天室 翻版吗
    xx19941215
        26
    xx19941215  
       2019-06-16 08:54:02 +08:00 via iPhone
    韩顺平老师课堂作业即视感
    wewin
        27
    wewin  
    OP
       2019-06-16 11:24:12 +08:00
    @kiwier
    @xx19941215
    @blless
    是基于韩老师的那个项目做的。想做个练手项目,自己也没好的想法,感觉老师这个点在还不错,就基于这个做了。目前和韩老师那个不同地方是加了点对点聊天和日志分级使用不同的颜色输出。后面计划添加服务端日志记录,以及增加其他聊天相关功能模块和文件传输功能。
    wewin
        28
    wewin  
    OP
       2019-06-16 11:25:04 +08:00
    @littlewing 前面也有别人提到,测试会加上。
    littlewing
        29
    littlewing  
       2019-06-16 12:35:04 +08:00 via iPhone
    @wewin 或者说不是要非得强调是高并发啊,改成用 go 实现了一个 im 的 demo
    rainmakeroly
        30
    rainmakeroly  
       2019-06-16 13:24:20 +08:00 via Android
    应该要有测试,或者如楼上说 不强调高并发。

    标题党在这里没用。觉得有用的自然会看。

    HikariCP Java 里的 连接池 它里面有基准测试和
    简单对比,以及其他测试
    mogging
        31
    mogging  
       2019-06-16 15:33:58 +08:00
    建议搞个端到端加密和无服务端存储(服务端只存元数据),再搞个易用的客户端,这样做大做强就会指日可待了
    kiwier
        32
    kiwier  
       2019-06-16 18:37:56 +08:00 via iPhone
    @wewin 加油
    shadeofgod
        33
    shadeofgod  
       2019-06-16 19:19:27 +08:00
    go 语言默认高并发 2333333333
    Tomotoes
        34
    Tomotoes  
       2019-06-16 19:46:18 +08:00   ❤️ 1
    这个项目真的是个坑...
    - 各种各样的拼写错误, 逼死强迫症
    - 没有用到包管理器 ,
    - 代码没有遵循 go 语言规范
    - 连一个像样的 readme 都没有..
    wewin
        35
    wewin  
    OP
       2019-06-16 23:00:51 +08:00
    @Tomotoes 本来就是随意写的,没想到有这么多人关注,会好好完善下的。
    wewin
        36
    wewin  
    OP
       2019-06-16 23:14:36 +08:00
    @rainmakeroly 好的,感谢建议,测试还没来得及高。但是我该怎么改标题,这里的 V2EX 的文章好像没法编辑
    wewin
        37
    wewin  
    OP
       2019-06-16 23:16:11 +08:00
    @mogging 端对端逃过了数据监控,法律怕是不允许呀。我不太了解,想着说的。
    feelinglucky
        38
    feelinglucky  
       2019-06-17 00:16:48 +08:00
    驼峰不建议,很明显的 Java 风格,文件命名建议用下划线

    还有,用例测试呢?
    feelinglucky
        39
    feelinglucky  
       2019-06-17 00:18:28 +08:00
    顺便提下,我写了个很简单的 pid file 文件生成库,应该对这个项目有帮助,自荐下
    feelinglucky
        40
    feelinglucky  
       2019-06-17 00:19:30 +08:00
    maxmin
        41
    maxmin  
       2019-06-17 09:33:54 +08:00
    message.go 定义的太简单了。 这个应该是基础,而且是最重要的,应该通过这个就可以看到你基本的通信的处理。
    另外对于 server 来说他应该不管是点对点 还是 group 的,和 client 之间交互 session 添加加上用户的 ID 即可转发。这样也方便做继续添加删除等处理。
    lanjz
        42
    lanjz  
       2019-06-17 10:49:22 +08:00
    ReadData() 中可以考虑使用 io.ReadFull()
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   894 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:51 · PVG 05:51 · LAX 13:51 · JFK 16:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.