A lightweight, database‑backed, two-user private chat application with real-time messaging, built using PHP, MySQL, WebSockets, and Docker.
Disclaimer: This academic prototype is not production‑ready. Messages are stored in plaintext in MySQL; only passwords are hashed via PHP’s
password_hash.
- Docker (Engine or Desktop)
- Docker Compose
- Familiarity with PHP & MySQL
-
Clone repository
git clone https://github.com/your-username/ChatApp.git cd ChatApp/ChatApp - Applicazione Finita -
Build and launch
docker-compose up --build
-
Access the services
- Web UI (static pages):
http://localhost(port 80) - WebSocket endpoint:
ws://localhost:8080 - MySQL:
localhost:3306(credentials defined indb/init.sql)
- Web UI (static pages):
ChatApp - Applicazione Finita/
├── docker-compose.yml # defines db, web, ws-server services
├── db/
│ ├── Dockerfile # MySQL 8.0 setup, timezone Europe/Rome
│ └── init.sql # schema: users, chats, messages, tokens
├── web/
│ ├── Dockerfile # PHP 8.2 + Apache configuration
│ ├── apache.conf # vhost & error pages
│ └── files/
│ ├── index.php # SPA entry point
│ ├── login.php # login UI
│ ├── register.php # register UI
│ ├── logout.php # logout handler
│ ├── errors/ # HTTP error pages
│ │ ├── 403.html
│ │ └── 404.html
│ └── backend/ # REST API handlers
│ ├── db.php
│ ├── e_register.php
│ ├── e_login.php
│ ├── check_user_existence.php
│ └── get_chats.php
└── ws-server/
├── Dockerfile # PHP 8.1 CLI + sockets extension
└── files/
├── db.php # PDO MySQL connection
└── ws.php # WebSocket server logic
- db/: Initializes
chat_appdatabase in MySQL container. - web/: Serves REST API and frontend via Apache+PHP.
- ws-server/: Handles WebSocket connections for real-time messaging.
Database: chat_app
| Table | Columns | Notes |
|---|---|---|
users |
id PK, username UNIQUE, password |
Password hashed via password_hash |
chats |
id PK, user1_id FK, user2_id FK,participant_pair GENERATED UNIQUE |
participant_pair enforces unique pairs |
messages |
id PK, chat_id FK, sender_id FK, content, sent_at TIMESTAMP |
|
tokens |
id PK, user_id FK, token |
WS authentication token |
All under web/files/backend/:
-
POST
/e_register.phpRequest:{ username, password }→ Creates new user. -
POST
/e_login.phpRequest:{ username, password }→ Starts PHP session, issues WS token. -
GET
/check_user_existence.php?username=<name>Response:{ status: success|error }. -
GET
/get_chats.phpResponse: JSON array of chats for user. Theuser_idis taken from the $_SESSION
The other PHP pages perform calls to these endpoints.
Located in web/files:
register.phpandlogin.phphandle user onboarding.index.phpprovides the live chat interface, displays all users' chats and manages the connection to the WebSocket server.- Static assets (
favicon.ico,default-avatar.jpg, imgs) are embedded or referenced.
The frontend uses JavaScript in index.php to:
-
Call REST API for login/registration and fetching chats.
-
Establish a WebSocket connection:
let ws = new WebSocket('ws://' + location.hostname + ':8082');
-
Send autentication request:
// Instruction for autentication
ws.onopen = () => {
// Trying autentication on opened connection
setTimeout(() => {
ws.send(JSON.stringify({
type: 'auth',
user_id: user_id,
token: token
}));
}, 100);
// Some other things
};- Send/receive messages in JSON frames.
In ws-server/files/ws.php:
- Setup: Binds TCP socket on
0.0.0.0:8080. - Handshake: Validates
user_idandtokenagainsttokenstable. - Loop: Uses
socket_select()to manage each socket in a always running loop. - Frame Handling: Helpers
readFrame()/sendFrame()to easily compose and receive new frames.
docker-compose down -vThis stops all containers and removes associated volumes.
Released under the MIT License. Feel free to fork, modify, and learn from this project.