https://github.com/knightchaser/gotcp
A simple CLI based multiuser chatting app with GO TCP socket, based on the client-server model
https://github.com/knightchaser/gotcp
chatting-app cli cli-app docker golang small-project socket socket-programming tcp
Last synced: about 1 year ago
JSON representation
A simple CLI based multiuser chatting app with GO TCP socket, based on the client-server model
- Host: GitHub
- URL: https://github.com/knightchaser/gotcp
- Owner: KnightChaser
- Created: 2024-01-12T00:34:05.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-01-15T14:22:55.000Z (over 2 years ago)
- Last Synced: 2025-03-31T07:22:19.300Z (about 1 year ago)
- Topics: chatting-app, cli, cli-app, docker, golang, small-project, socket, socket-programming, tcp
- Language: Go
- Homepage: https://pkg.go.dev/net
- Size: 8.88 MB
- Stars: 7
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# goTCP




A simple **real time** multiuser chatting application with TCP socket, based on the client-server model, built with Go. Every instance is dockerized and automated by scripts for rapid setup.
> Demonstration(picture)

This simple project is a simple real-time chat application(because it's simple, please consider the naive interfaces.) implemented in the Go programming language. It consists of a server (`tcpserver/tcpserver.go`) and a client (`tcpclient/tcpclient.go`) that communicate over a TCP network. The application allows users to connect to the server, set a username, and exchange messages in real time.
### Feature
* **Server-Client Architecture**: The application follows a server-client architecture, enabling multiple users to connect to the server simultaneously.
* **Real-Time Messaging**: Users can exchange messages in real time. When a user sends a message, it is immediately broadcast to all other connected users.
* **Username Registration**: Users are prompted to set a username when connecting to the server. This username is used to identify users in the chat.
* **Graceful Termination**: Users can terminate their connection gracefully by typing `!exit` in the client interface, triggering a clean disconnection from the server. In server, you can just stop server process via hitting `[ctrl]+[c]` keybinding. It will gracefully terminate the whole session.
* **Dockerized**: Server and client are encapsulated by docker. Because there are few lines of docker-related commands for every instance, this project provides a "one-stop script" that processes setting up, docker building, and docker execution at once
* [x] Windows(Powershell script(`dockerbuild.ps1`))
* [x] Linux(Shell script(`dockerbuild.sh`))
### Execution
Because this project's theme is communicating with each other, the docker networking setup is very important. You just need to execute the "one-stop script" that this project provides. **Support both Windows and Linux!**
* **Server**: `tcpserver\dockerbuild.ps1` if **Windows**, `sudo bash tcpserver/dockerbuild.sh` if **Linux** (Only one instance is required, so execute this script only once at the same time.)
* **Client**: `tcpclient\dockerbuild.ps1` if **Windows**, `sudo bash tcpclient/dockerbuild.sh` if **Linux** (You may create client instances as many as you want.)
### Docker setup explanation (networking)
* **Server** (Windows Powershell)
```powershell
docker network remove goTCPnet
docker network create goTCPnet --subnet=192.168.111.0/24
docker build . --tag gotcpserver:0.1
docker run --rm --name gotcpserver --network goTCPnet --ip 192.168.111.111 -p 7777:7777 gotcpserver:0.1
```
Because the server accepts clients' requests remotely, IP address and port settings should be synchronized. By default, server setup creates a docker network `goTCPnet` and designates the network range as `192.168.111.0/24`, server process address as `192.168.111.111(/24)` manually. This setting should be synchronized with `tcpserver\tcpserver.go`'s `listeningAddressPort` variable that the server process refers to for setting up the address to accept clients' requests.
```go
listeningAddressPort := "192.168.111.111:7777"
```
* **Client** (Windows Powershell)
```powershell
# Get the USERNAME from user input
$USERNAME = Read-Host "Enter USERNAME "
Write-Output "You're now @$USERNAME"
# Generate a 6-digit random hex string (to make every container have different container names)
$RandomHex = -join ((1..6) | ForEach-Object { Get-Random -Minimum 0 -Maximum 16 } | ForEach-Object { $_.ToString("X") })
$containerName = "gotcpclient${USERNAME}${RandomHex}"
# Build and run Docker container
docker build -t gotcpclient:0.1 --build-arg --no-cache .
docker run --rm --network goTCPnet --interactive --tty --name $containerName gotcpclient:0.1 ./tcpclient -username $USERNAME
```
Because the client (`tcpclient\tcpclient.go`) accepts username as an argument `-username`, It asks a user for the username for every single created instance and applies them to the execution arguments. Suppose users may use multiple same names(`-username` argument). In that case, there might be some unexpected docker container name collisions, so client setup appends a 6-digit random hexadecimal string like `gotcpclient${USERNAME}${RandomHex}` to ensure every client container name should be globally unique. Client processes should be interactive to receive and print messages from users and server instances, `--interactive` and `--tty` options should be provided too.
### Note and contribution
* Because this was made for learning how to make "something" with Go, Docker, Socket communication, and Github, the implementation is naive and not-so-professional, I kindly ask for your consideration.
* Any contribution to this project is greatly appreciated.
**@KnightChaser**, a pro spaghetti chef in Gachon University, Cybersecurity department.