This guide explains how to set up and run a local environment using Minikube, Helm, Docker, Go, and the required services (PostgreSQL, Kafka, Auth, WebSocket, and Persistence).
Make sure you have the following tools installed:
minikube startAdd the Bitnami repository and update:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo updatePostgreSQL:
helm install postgres bitnami/postgresql -f charts/postgresql/values.yamlKafka:
helm install kafka bitnami/kafka -f charts/kafka/values.yamlkubectl create secret generic auth-service-secret --from-literal=jwtSecret=secret-token-hereBefore each build, run:
eval $(minikube docker-env)WebSocket Service:
docker build -f websocket/Dockerfile -t websocket-service .
kubectl delete deployment websocket-service --ignore-not-found
kubectl apply -f deployments/websocket/websocket-deployment.yamlAuth Service:
docker build -f auth/Dockerfile -t auth-service .
kubectl delete deployment auth-service --ignore-not-found
kubectl apply -f deployments/auth/auth-deployment.yamlPersistence Service:
docker build -f persistence/Dockerfile -t persistence-service .
kubectl delete deployment persistence-service --ignore-not-found
kubectl apply -f deployments/persistence/persistence-deployment.yamlWebSocket Service:
kubectl port-forward service/websocket-service 30080:80PostgreSQL:
kubectl port-forward svc/postgres-postgresql 5432:5432Auth Service:
kubectl port-forward deployment/auth-service 8081:8081Below is a brief explanation of the main services in this project and their responsibilities:
| Method | Route | Description |
|---|---|---|
| POST | localhost:8081/login |
Login for access token |
| Method | Route | Description |
|---|---|---|
| GET | ws://localhost:30080/ws |
Websocket server |
Responsible for creating and validating JWT tokens. It provides authentication endpoints that other services use to verify if a client is authorized.
The client must send a JSON payload containing username and password. The Auth Service checks if the user exists in the database and if the credentials are correct. If authentication is successful, a JWT token is generated and returned in the response.
Example request:
POST /login
{
"username": "your_username",
"password": "your_password"
}curl -X POST http://localhost:8081/login -H "Content-Type: application/json" -d '{"username":"your_username","password":"your_password"}'Example response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}When a client connects to the WebSocket Service, the first message sent by the client must be a valid JWT token. The WebSocket Service forwards this token to the Auth Service for validation.
- If the token is valid, the client is authenticated and allowed to send and receive broadcast messages.
- If the first message is not a valid JWT token, the connection is immediately closed.
Important: While the client is not authenticated, it cannot send or receive any broadcast messages. Only after successful authentication (valid token) does the client gain access to the messaging system.
This flow ensures that only authenticated users can participate in the real-time messaging system, providing both security and control over client communications.
Manages client connections via WebSocket. For each client, it checks authentication by communicating with the Auth Service. Only authenticated clients can send and receive messages.
Messages sent by clients are published to the Kafka topic websocket-messages. The WebSocket Service also consumes this topic to broadcast messages to all connected and authenticated clients.
Consumes messages from the websocket-messages Kafka topic. Its main responsibility is to persist all messages sent by clients into the PostgreSQL database. This ensures that messages are not lost, even if there are issues with broadcasting to clients.
Acts as the message broker between services. All client messages are sent to the websocket-messages topic, which is consumed by both the WebSocket Service (for broadcasting) and the Persistence Service (for storage).
Stores all messages received from the Persistence Service, providing durability and reliability for message history and recovery.
This architecture ensures secure authentication, reliable message delivery, and data persistence for all client communications.
Below are example usage scenarios for interacting with the application:
After completing the port forwarding steps, open index.html in your browser. This page provides a simple interface to connect to the WebSocket server.
-
Generate a JWT Token: Use the
/loginendpoint to authenticate with your username and password. The response will include a JWT token. -
Connect to the WebSocket Server: Use the interface in
index.htmlto establish a WebSocket connection. -
Authenticate: As the first message, send your JWT token through the WebSocket connection. If the token is valid, you will be authenticated and added to the hub of authenticated clients.
-
Send and Receive Messages: Once authenticated, you can send and receive real-time messages. Example message format:
{ "id": "023e4567-e89b-12d3-a456-426614174000", "content": "Player 7 pick one cards.", "timestamp": "2024-05-11T15:30:00Z" }When you send a message:
- It is published to the Kafka topic
websocket-messages. - The Persistence Service consumes the message and saves it to PostgreSQL.
- The WebSocket Service also consumes the message and broadcasts it to all authenticated clients in real time.
- It is published to the Kafka topic
If you open index.html and connect to the WebSocket server, but the first message you send is not a valid JWT token, the server will immediately close your connection.
Note: Clients must be authenticated before they can send or receive any broadcast messages. Only after successful authentication (by sending a valid JWT token as the first message) will the client be able to participate in real-time messaging.
This flow ensures secure, real-time communication where only authenticated users can interact with the system.
- Make sure your Docker context is set to Minikube (
eval $(minikube docker-env)) before building images. - To update images, repeat the build process and re-apply the deployment.
- The configuration files (
values.yamlanddeployment.yaml) should be properly set up according to your needs.