The distributed chat system based on golang supports one-to-one chat, chat room and other functions. In order to facilitate the test, the sent message data has not been stored in the database temporarily, it will be added to the database later, or you can add it to the database by yourself, which is convenient for permanent storage of chat content, and supports functions such as message must be reached.

Dependent package

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

Package description:

redis: used to cache ws server information and maintain ws server information in the form of heartbeat.

gin: implement web services

websocket: implement the websocket protocol

rpcx: server builds rpc communication

Architecture diagram

One-to-one messaging

  • The client sends a request to establish a long connection, which is distributed to one of the ws servers (here, assuming that the A server is assigned) after nginx load balancing.
  • The A server responds to the long connection request and caches the client address and user connection, user id and other information.
  • The client receives the response from the server to establish a websocet connection.
  • The client sends information, and nginx load balancing is allocated to one of the ws servers (here, it is assumed to be the B server).
  • Server B parses the received user (assuming a) information from the sent information, first verifies whether user a has established a websocet connection with server B, and if established, sends the message directly to user a. Otherwise, obtain the WS server information list from the redis cache, and send the message to every WS server in the WS server list except for the B server through the rpc method. These WS servers that receive the information will first verify whether a connection is established with the a user. If established, send the information to user a, otherwise discard it.

Group message

  • The client sends a request to establish a long connection, which is distributed to one of the ws servers (here, assuming that the A server is assigned) after nginx load balancing.
  • The A server responds to the long connection request and caches the client address and user connection, user id and other information.
  • The client receives the response from the server to establish a websocet connection.
  • The client sends information, and nginx load balancing is allocated to one of the ws servers (here, it is assumed to be the B server).
  • The B server parses out the group information from the sent information, obtains the user list according to the group information, and traverses the user sending information (the sending method is similar to one-to-one).
  • First, verify whether the user has established a websocet connection with the B server, and if it is established, send a message directly to the user. Otherwise, obtain the WS server information list from the redis cache, and send the message to every WS server in the WS server list except for the B server through the rpc method. These WS servers that receive the information will first verify whether the connection is established with the user, and establish Send the information to the user, otherwise discard it.

Quickly build

1. Pull the code
git clone https://github.com/guyan0319/go-websocket.git

Note: This code version control uses go modules

2. Operating system
go run main.go
3. Configure 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. Test one-to-one chat

The browser opens two windows to access

http://ws.test/home/index?uid=1&to_uid=2

http://ws.test/home/index?uid=2&to_uid=1

5. Test group chat

The browser opens two windows to access

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

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

Relevant information:

github.com/gorilla/websocket

https://my.oschina.net/u/4231722/blog/3168223

https://doc.rpcx.io/

https://github.com/link1st/gowebsocket

https://segmentfault.com/a/1190000018712908


guyan0319
1.5k 声望721 粉丝

坚持但不盲目