diff --git a/README.md b/README.md index a2fe4c6..fc8b7a4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Чат с общей комнатой -Веб-приложение чата с одной общей комнатой на WebSocket. Поддерживает текстовые сообщения, отправку файлов и отображение изображений. +Веб-приложение чата с одной общей комнатой на WebSocket. +Текстовые сообщения, файлы, изображения, аудио, видео и голосовые сообщения. **Сервер:** Node.js + `ws` **Клиент:** React + Vite @@ -18,7 +19,7 @@ npm install npm start ``` -Запускает WebSocket сервер на `ws://localhost:8080`. +WebSocket сервер на `ws://localhost:8080`. ### Клиент @@ -28,8 +29,8 @@ npm install npx vite ``` -Запускает dev-сервер на `http://localhost:3000`. -В режиме разработки клиент подключается напрямую к `ws://localhost:8080`. +Dev-сервер на `http://localhost:3000`. +Клиент подключается напрямую к `ws://localhost:8080`. ### Пользователи по умолчанию @@ -42,15 +43,10 @@ npx vite ## Production (Docker) -### Сборка образа +### Сборка и запуск ```bash docker build -t chat-app . -``` - -### Запуск контейнера - -```bash docker run -d -p 80:80 chat-app ``` @@ -59,11 +55,12 @@ docker run -d -p 80:80 chat-app ### Как это работает - **nginx** на порту 80 раздаёт статику React и проксирует WebSocket -- Путь `/` → статические файлы клиента (`index.html`, JS, CSS) -- Путь `/ws` → прокси на Node.js WebSocket сервер (порт 8080 внутри контейнера) +- Путь `/` → статические файлы клиента +- Путь `/ws` → прокси на Node.js сервер (порт 8080 внутри контейнера) - nginx поддерживает Upgrade до WebSocket, таймаут соединения — 24 часа - Максимальный размер загружаемых файлов через nginx — 50 МБ -- После остановки Node.js контейнер завершается (через `wait`) +- **Auto-restart:** если Node.js сервер упал, entrypoint перезапускает его через 1 секунду +- Чистое завершение (exit 0, SIGTERM) — контейнер останавливается без перезапуска --- @@ -77,8 +74,6 @@ docker run -d -p 80:80 chat-app | `MAX_FILE_SIZE` | `10485760` (10 МБ) | Максимальный размер файла в байтах | | `USERS_FILE` | `users.json` | Путь к файлу с пользователями | -Пример: - ```bash $env:PORT=9090; $env:MAX_FILE_SIZE=2097152; node server.js ``` @@ -89,9 +84,7 @@ $env:PORT=9090; $env:MAX_FILE_SIZE=2097152; node server.js |-----------|-------------------|--------------------------|---------| | `VITE_WS_URL` | `ws://localhost:8080` | `/ws` | URL WebSocket сервера | -Настройки хранятся в файлах: -- `client/.env.development` — для `npx vite` (dev-режим) -- `client/.env` — для `vite build` (production-сборка) +Настройки в `client/.env.development` (dev) и `client/.env` (production). --- @@ -99,81 +92,54 @@ $env:PORT=9090; $env:MAX_FILE_SIZE=2097152; node server.js ### Аутентификация -Клиент → Сервер: - ```json +// → сервер { "type": "auth", "login": "alice", "password": "123" } -``` - -Сервер → Клиент: - -```json +// ← ответ { "type": "auth_result", "success": true } -``` - -```json { "type": "auth_result", "success": false, "reason": "Invalid login or password" } ``` ### Текстовое сообщение -Клиент → Сервер: - ```json +// → сервер { "type": "text", "text": "Привет!" } -``` - -Сервер → Все: - -```json +// ← всем { "type": "text", "from": "alice", "timestamp": 1717000000000, "text": "Привет!" } ``` -### Файл / изображение - -Клиент → Сервер: +### Файл / изображение / аудио / видео ```json -{ - "type": "file", - "filename": "cat.png", - "mime": "image/png", - "data": "" -} +// → сервер +{ "type": "file", "filename": "cat.png", "mime": "image/png", "data": "" } +// ← всем (от сервера добавлены from и timestamp) +{ "type": "file", "from": "alice", "timestamp": 1717000000000, "filename": "cat.png", "mime": "image/png", "data": "" } ``` -Сервер → Все (такая же структура, добавлены `from` и `timestamp`): - -```json -{ - "type": "file", - "from": "alice", - "timestamp": 1717000000000, - "filename": "cat.png", - "mime": "image/png", - "data": "" -} -``` +Клиент определяет тип файла по MIME: `image/*` — картинка, `audio/*` — плеер, `video/*` — плеер, остальное — скачивание. ### Системные сообщения -Сервер → Все: - ```json { "type": "system", "text": "alice joined the chat" } +{ "type": "system", "text": "alice left the chat" } ``` --- ## Функциональность -- **Текстовые сообщения** — отображаются с логином отправителя и временем -- **Файлы** — любые типы, до 10 МБ (настраивается). Файлы передаются через base64 в JSON -- **Изображения** — автоматически определяются по MIME-типу (`image/*`), рендерятся как ``, клик открывает в новой вкладке -- **Не-изображения** — отображаются как ссылка для скачивания с именем файла -- **Уведомления на неактивной вкладке** — звуковой сигнал (Web Audio API) и красная точка на favicon -- **Системные сообщения** — подключение / отключение участников -- **Скролл** — автоматический, кастомный тонкий скроллбар в теме приложения +- **Текстовые сообщения** — логин отправителя, время, ссылки (http/https) автоматически становятся кликабельными +- **Файлы** — любые типы, до 10 МБ (настраивается), base64 в JSON +- **Изображения** — `image/*` → ``, клик открывает в новой вкладке +- **Аудио** — `audio/*` → `