Golang-based distributed chat system, support for one-on-one chat, chat room and other functions. In order to test the convenience of sending messages data is not stored in the database, later will be added to the database, can also be added to the database, convenient permanent storage chat content, and support the message must reach and other functions.

Depend on the package

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

Package:

Redis: used to cache WS server information and maintain WS server information in the form of heartbeat.

Gin: Implements web services

Websocket: implements the WebSocket protocol

RPCX: The server establishes RPC communication

Architecture diagram

One-to-one messaging

  • The client sends A persistent connection request, which is processed by nGINx load balancing to one of the WS servers (assuming server A is assigned here).
  • A The server responds to the persistent connection request and caches information such as the client address, user connection, and user ID.
  • The client receives a response from the server to establish a WebSocET connection.
  • The client sends the information, and the NGINx load balance is distributed to one of the WS servers (assume B server here).
  • Server B parses and receives user A’s information from the sent information. Server B first verifies whether the WebSocET connection is established between user A and server B. If the connection is established, server B directly sends a message to user A. Otherwise, it obtains the WS server information list from the Redis cache and sends messages to each WS server except server B in RPC mode. These WS servers that receive the sent information verify whether the connection is established with user A, and then send the information to user A. Otherwise, the message is discarded.

Group-sent message

  • The client sends A persistent connection request, which is processed by nGINx load balancing to one of the WS servers (assuming server A is assigned here).
  • A The server responds to the persistent connection request and caches information such as the client address, user connection, and user ID.
  • The client receives a response from the server to establish a WebSocET connection.
  • The client sends the information, and the NGINx load balance is distributed to one of the WS servers (assume B server here).
  • B The server parses the group information from the sent information, obtains the user list based on the group information, and traverses the sent information (sending mode is similar to one-to-one).
  • Verify whether a webSocET connection is established between the user and server B. If the connection is established, the user directly sends a message to the user. Otherwise, it obtains the WS server information list from the Redis cache and sends messages to each WS server except server B in RPC mode. These WS servers that receive the sent information verify whether the connection is established with the user. If the connection is established, it sends the information to the user.

Quickly build

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

Note: Code versioning here uses Go Modules

2. Run the system
go run main.go
3. Configure nginx
Upstream go-http {server 127.0.0.1:8282 weight=1 max_fails=2 fail_timeout=10; upstream go-http {server 127.0.0.1:8282 weight=1 max_fails=2 fail_timeout=10; 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-on-one chats

The browser opens two Windows to access

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

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

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

Related information:

github.com/gorilla/websocket

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

https://doc.rpcx.io/

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

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