go-websocket 分佈式IM

基於golang實現的分佈式聊天系統,支持一對一聊天,聊天室等功能。爲了測試方便發送消息數據暫未存入數據庫,後期會加入數據庫,也可自行加入數據庫,方便永久存儲聊天內容,以及支持消息必達等功能。php

依賴包

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

包說明:nginx

redis :用於緩存ws服務器信息,用心跳形式維護ws服務器信息。git

gin:實現web服務github

websocket: 實現websocket協議golang

rpcx:服務器建rpc通訊web

架構圖

一對一發消息

  • 客戶端 發送創建長鏈接請求,通過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服務器,先驗證和用戶是否創建鏈接,創建則發送信息給用戶,不然丟棄。

快速搭建

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

注:這裏代碼版本控制使用go modulesredis

二、運行系統
go run main.go
三、配置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;
    }
}
四、測試一對一聊天

瀏覽器打開兩個窗口訪問數據庫

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

http://ws.test/home/index?uid...瀏覽器

五、測試羣聊天

瀏覽器打開兩個窗口訪問

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...

相關文章
相關標籤/搜索