{"id":15056723,"url":"https://github.com/minghsu0107/go-random-chat","last_synced_at":"2025-04-08T12:09:42.895Z","repository":{"id":45515539,"uuid":"457877635","full_name":"minghsu0107/go-random-chat","owner":"minghsu0107","description":"Modern real-time chat in scalable architecture.","archived":false,"fork":false,"pushed_at":"2025-01-25T03:04:40.000Z","size":610,"stargazers_count":397,"open_issues_count":3,"forks_count":44,"subscribers_count":5,"default_branch":"kafka","last_synced_at":"2025-04-01T11:03:46.367Z","etag":null,"topics":["cassandra","chat","go","kafka","messaging","microservices","random-chat","real-time","redis"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/minghsu0107.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-10T17:22:09.000Z","updated_at":"2025-03-27T07:17:21.000Z","dependencies_parsed_at":"2023-12-13T08:55:06.724Z","dependency_job_id":"7248a87d-14a7-49b9-84b9-a31e641d9410","html_url":"https://github.com/minghsu0107/go-random-chat","commit_stats":null,"previous_names":[],"tags_count":59,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minghsu0107%2Fgo-random-chat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minghsu0107%2Fgo-random-chat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minghsu0107%2Fgo-random-chat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minghsu0107%2Fgo-random-chat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/minghsu0107","download_url":"https://codeload.github.com/minghsu0107/go-random-chat/tar.gz/refs/heads/kafka","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247838444,"owners_count":21004580,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cassandra","chat","go","kafka","messaging","microservices","random-chat","real-time","redis"],"created_at":"2024-09-24T21:55:49.969Z","updated_at":"2025-04-08T12:09:42.873Z","avatar_url":"https://github.com/minghsu0107.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go Random Chat\n![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/minghsu0107/go-random-chat?label=Version\u0026sort=semver)\n![CI status api](https://github.com/minghsu0107/go-random-chat/actions/workflows/docker-api-dev.yml/badge.svg)\n\nModern real-time chat platform in scalable architecture, written in go. \n\nKafka is used for message Pub/Sub. Checkout [this branch](https://github.com/minghsu0107/go-random-chat/tree/redis) for the Redis Pub/Sub version.\n\n## Overview\n\n### System architecture\n\n\u003cimg width=\"1028\" alt=\"image\" src=\"https://github.com/minghsu0107/go-random-chat/assets/50090692/81733303-b022-4069-91c0-1d0360bede7f\"\u003e\n\n\n### Features\n- Real-time communication and efficient websocket handling using [Melody](https://github.com/olahol/melody).\n- Microservices architecture. All services **are stateless** and can be horizontally scaled on demand.\n  - `web`: frontend server\n  - `user`: user account server\n  - `match`: user matching server\n  - `chat`: messaging server\n  - `forwarder`: message forwarding server that maps message receivers to specific `chat` servers\n  - `uploader`: file uploader\n- Use gRPC for inter-service communication\n  - with retry, timeout, and circuit breaker\n- Use [cobra](https://github.com/spf13/cobra) and [viper](https://github.com/spf13/viper) for CLI and configuration management respectively.\n- Dependency injection using [wire](https://github.com/google/wire).\n- Graceful shutdown.\n- Observability using [Golang Prometheus client](https://github.com/prometheus/client_golang) for monitoring and [opentelemetry-go](https://github.com/open-telemetry/opentelemetry-go) for tracing.\n- At-least-once delivery for message Pub/Sub using [Kafka](https://kafka.apache.org).\n- Persist messages and chat channel metadata in [Cassandra](https://cassandra.apache.org), an open source NoSQL distributed database for scalability and high availability.\n- Automatically generate RESTful API documentation with Swagger 2.0.\n- User login session management using http-only cookie.\n- Support Google OAuth2 login.\n- User matching with idempotency.\n- Chat channel authentication using JWT.\n- S3-compatible object storage for uploaded files.\n- Channel-level file access control using S3 presigned URLs.\n- Support uploading images from clipboard.\n- Use [Traefik FowardAuth](https://doc.traefik.io/traefik/middlewares/http/forwardauth/) for file upload authentication.\n- Protect file upload api with distributed rate limiting (token bucket algorithm).\n- Message seen feature.\n- Auto-scroll to the first unseen message.\n- Persist chat history on browser close or page refresh.\n- Automatic websocket reconnection.\n- Responsive web design.\n\n### Screenshots\n\u003cimg src=\"https://user-images.githubusercontent.com/50090692/202243227-022dfe85-c36c-49d0-a46d-7db1d2bae16f.png\" alt=\"\" data-canonical-src=\"https://user-images.githubusercontent.com/50090692/202243227-022dfe85-c36c-49d0-a46d-7db1d2bae16f.png\" width=\"50%\" height=\"50%\" /\u003e\n\n\u003cimg src=\"https://i.imgur.com/4ctofQv.png\" alt=\"\" data-canonical-src=\"https://i.imgur.com/4ctofQv.png\" width=\"40%\" height=\"40%\" /\u003e\n\n\u003cimg src=\"https://user-images.githubusercontent.com/50090692/157266585-90082195-0517-47a2-a1ef-20d72fa3a3e6.png\" alt=\"\" data-canonical-src=\"https://user-images.githubusercontent.com/50090692/157266585-90082195-0517-47a2-a1ef-20d72fa3a3e6.png\" width=\"40%\" height=\"40%\" /\u003e\n\n\u003cimg src=\"https://user-images.githubusercontent.com/50090692/156815192-11a251fb-32ee-4888-b79c-aa64c97b407d.png\" alt=\"\" data-canonical-src=\"https://user-images.githubusercontent.com/50090692/156815192-11a251fb-32ee-4888-b79c-aa64c97b407d.png\" width=\"40%\" height=\"40%\" /\u003e\n\n## Getting Started\n\nPrerequisite:\n- Docker-Compose v2\n- Root permission\n\nFirst, [create OAuth client ID credentials](https://developers.google.com/workspace/guides/create-credentials#web-application) and replace `USER_OAUTH_GOOGLE_CLIENTID` and `USER_OAUTH_GOOGLE_CLIENTSECRET` with your credentials in `run.sh`.\n\nExample setting:\n\n\u003cimg src=\"https://user-images.githubusercontent.com/50090692/207066730-cbfd869e-9658-46ea-94a9-c3c329cd5731.png\" alt=\"\" data-canonical-src=\"https://user-images.githubusercontent.com/50090692/207066730-cbfd869e-9658-46ea-94a9-c3c329cd5731.png\" width=\"40%\" height=\"40%\" /\u003e\n\nTo run locally, execute the following command:\n```bash\ncd deployments\nsudo ./run.sh add-host\n./run.sh start\n```\n`run.sh add-host` needs root permission to alias `minio` to `localhost` in `/etc/hosts`.\n\nCheck cassandra connection:\n```\ndocker exec deployments-cassandra-1 bash -c \"cat /opt/bitnami/cassandra/logs/cassandra.log\"\ndocker exec deployments-cassandra-1 bash -c \"cqlsh -u ming -p cassandrapass\"\n```\nThis will spin up all services declared in `docker-compose.yaml`. Visit `http://localhost` and you will see the application home page.\n\nBucket `myfilebucket` will be created automatically on `minio` by `createbucket`. However, if `minio` is still initializing after 5 retries of `createbucket`, the bucket creation will fail. If this happens, please run the following command once `minio` is up and running:\n```bash\ndocker restart deployments-createbucket-1\n```\n\n- Visit `http://localhost` for the application home page.\n- Visit `http://localhost:8080` for Traefik dashboard.\n- VIsit `http://localhost:9001` for Minio dashboard.\n- Visit `http://localhost:9090` for Prometheus dashboard.\n- Visit `http://localhost:16686` for Jaeger dashboard.\n- Visit `http://localhost/api/\u003csvc\u003e/swagger/index.html` for API documentation, where `\u003csvc\u003e` could be `user`, `match`, `chat`, or `uploader`.\n\nExample configuration: [config.example.yaml](configs/config.example.yaml).\n## Deploy with SSL\nA common scenario is that one deploys the application behind a reverse proxy with SSL termination. If that is your case, remember to correctly configure your proxy for websocket. For example, in Google Cloud Platform, for websocket traffic sent through a Google Cloud external HTTP(S) load balancer, the backend service timeout is interpreted as the maximum amount of time that a WebSocket connection can remain open, whether idle or not. Therefore, you may want to use a `timeoutSec` value larger than the default 30 seconds in your `BackendConfig`.\n## Docker Tagging Rules\n| Event          | Ref                        | Docker Tags                |\n| -------------- | -------------------------- | -------------------------- |\n| `pull_request` | `refs/pull/2/merge`        | `pr-2`                     |\n| `push`         | `refs/heads/master`        | `master`                   |\n| `push`         | `refs/heads/releases/v1`   | `releases-v1`              |\n| `push tag`     | `refs/tags/v1.2.3`         | `v1.2.3`, `latest`         |\n| `push tag`     | `refs/tags/v2.0.8-beta.67` | `v2.0.8-beta.67`, `latest` |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminghsu0107%2Fgo-random-chat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fminghsu0107%2Fgo-random-chat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminghsu0107%2Fgo-random-chat/lists"}