乐趣区

关于golang:gowebsocket-分布式IM

基于 golang 实现的分布式聊天零碎,反对一对一聊天,聊天室等性能。为了测试不便发送音讯数据暂未存入数据库,前期会退出数据库,也可自行退出数据库,不便永恒存储聊天内容,以及反对音讯必达等性能。

依赖包

github.com/go-redis/redis
github.com/gin-gonic/gin
github.com/gorilla/websocket
github.com/smallnest/rpcx

包阐明:

redis:用于缓存 ws 服务器信息,用心跳模式保护 ws 服务器信息。

gin:实现 web 服务

websocket:实现 websocket 协定

rpcx:服务器建 rpc 通信

架构图

一对一发消息

  • 客户端 发送建设长连贯申请,通过 nginx 负载平衡调配给其中一台 ws 服务器(这里假如调配的是 A 服务器)解决。
  • A 服务器响应长连贯申请,并缓存客户端地址和用户连贯,用户 id 等信息。
  • 客户端收到服务端响应建设 websocet 连贯。
  • 客户端发送信息,nginx 负载平衡调配给其中一台 ws 服务器(这里假如是 B 服务器)。
  • B 服务器从发送的信息中解析接管用户(假如为 a)信息,先验证 a 用户是否和 B 服务器建设 websocet 连贯,若建设则间接发送音讯给 a 用户。否则通过 redis 缓存中获取 ws 服务器信息列表,通过 rpc 形式发送音讯到 ws 服务器列表中除 B 服务器之外的每台 ws 服务器,这些接管到发送信息的 ws 服务器,先验证和 a 用户是否建设连贯,建设则发送信息给 a 用户,否则抛弃。

群发音讯

  • 客户端 发送建设长连贯申请,通过 nginx 负载平衡调配给其中一台 ws 服务器(这里假如调配的是 A 服务器)解决。
  • A 服务器响应长连贯申请,并缓存客户端地址和用户连贯,用户 id 等信息。
  • 客户端收到服务端响应建设 websocet 连贯。
  • 客户端发送信息,nginx 负载平衡调配给其中一台 ws 服务器(这里假如是 B 服务器)。
  • B 服务器从发送的信息中解析出群信息,依据群信息获取用户列表,遍历用户发送信息(发送形式跟一对一相似)。
  • 先验证用户是否和 B 服务器建设 websocet 连贯,若建设则间接发送音讯给用户。否则通过 redis 缓存中获取 ws 服务器信息列表,通过 rpc 形式发送音讯到 ws 服务器列表中除 B 服务器之外的每台 ws 服务器,这些接管到发送信息的 ws 服务器,先验证和用户是否建设连贯,建设则发送信息给用户,否则抛弃。

疾速搭建

1、拉取代码
git clone https://github.com/guyan0319/go-websocket.git

注:这里代码版本控制应用 go modules

2、运行零碎
go run main.go
3、配置 nginx
upstream  go-http
{
    server 127.0.0.1:8282 weight=1 max_fails=2 fail_timeout=10s;
    keepalive 16;
}

upstream  go-ws
{
    server 127.0.0.1:8089 weight=1 max_fails=2 fail_timeout=10s;
    keepalive 16;
}

server {
        listen        80;
        server_name  ws.test;
        root   "D:/phpstudy/WWW/";
          location /ws {
        proxy_set_header Host $host;
        proxy_pass http://go-ws;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Connection "";
        proxy_redirect off;
        proxy_intercept_errors on;
        client_max_body_size 10m;
    }

    location /
    {
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header Host $host;
        proxy_pass http://go-http;
    }
}
4、测试一对一聊天

浏览器关上两个窗口拜访

http://ws.test/home/index?uid…

http://ws.test/home/index?uid…

5、测试群聊天

浏览器关上两个窗口拜访

http://ws.test/home/room?uid=1

http://ws.test/home/room?uid=2

相干材料:

github.com/gorilla/websocket

https://my.oschina.net/u/4231…

https://doc.rpcx.io/

https://github.com/link1st/go…

https://segmentfault.com/a/11…

退出移动版