Files
min-chat/README.md
T
Комаров Данил Анатольевич 6 63bf73d2c4 Полный рефакторинг сервера и клиента, голосовые сообщения, аудио/видео, Docker
Сервер:
- Вынесена конфигурация в server/config.js (порт, размер файла из env)
- Вынесена аутентификация в server/auth.js (загрузка users.json, authenticate())
- Вынесено управление соединениями в server/clients.js (createJsonSender, broadcast, validateFile)
- server/server.js стал точкой входа — минимальный код

Клиент:
- Вынесены хуки: hooks/useWebSocket.js (WebSocket + auth), hooks/useChatMessages.js (сообщения + уведомления)
- Вынесены утилиты: utils/blob.js (base64 → Blob URL), utils/linkify.jsx (URL → ссылки), utils/notify.js (звук + favicon)

Новые функции:
- VoiceRecorder — запись голоса через MediaRecorder, отправка как файл
- Аудио/видео плеер в Message (audio/*, video/* с controls)
- URL linkification — http/https ссылки автоматически кликабельны
- Звуковое уведомление (Web Audio API) при сообщении на неактивной вкладке
- Красная точка на favicon при непрочитанных сообщениях

Инфраструктура:
- docker-entrypoint.sh: авто-перезапуск Node.js сервера при падении
- Обновлён README.md: новая структура проекта, список функций, примеры
- Кастомный тонкий скроллбар в Message.css
2026-05-29 05:23:22 +03:00

187 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Чат с общей комнатой
Веб-приложение чата с одной общей комнатой на WebSocket.
Текстовые сообщения, файлы, изображения, аудио, видео и голосовые сообщения.
**Сервер:** Node.js + `ws`
**Клиент:** React + Vite
**Прокси:** nginx (production-сборка)
---
## Быстрый запуск (разработка)
### Сервер
```bash
cd server
npm install
npm start
```
WebSocket сервер на `ws://localhost:8080`.
### Клиент
```bash
cd client
npm install
npx vite
```
Dev-сервер на `http://localhost:3000`.
Клиент подключается напрямую к `ws://localhost:8080`.
### Пользователи по умолчанию
| Логин | Пароль |
|-------|--------|
| alice | 123 |
| bob | 456 |
---
## Production (Docker)
### Сборка и запуск
```bash
docker build -t chat-app .
docker run -d -p 80:80 chat-app
```
Открой `http://localhost`.
### Как это работает
- **nginx** на порту 80 раздаёт статику React и проксирует WebSocket
- Путь `/` → статические файлы клиента
- Путь `/ws` → прокси на Node.js сервер (порт 8080 внутри контейнера)
- nginx поддерживает Upgrade до WebSocket, таймаут соединения — 24 часа
- Максимальный размер загружаемых файлов через nginx — 50 МБ
- **Auto-restart:** если Node.js сервер упал, entrypoint перезапускает его через 1 секунду
- Чистое завершение (exit 0, SIGTERM) — контейнер останавливается без перезапуска
---
## Переменные окружения
### Сервер
| Переменная | По умолчанию | Описание |
|-----------|-------------|---------|
| `PORT` | `8080` | Порт WebSocket сервера |
| `MAX_FILE_SIZE` | `10485760` (10 МБ) | Максимальный размер файла в байтах |
| `USERS_FILE` | `users.json` | Путь к файлу с пользователями |
```bash
$env:PORT=9090; $env:MAX_FILE_SIZE=2097152; node server.js
```
### Клиент
| Переменная | По умолчанию (dev) | По умолчанию (production) | Описание |
|-----------|-------------------|--------------------------|---------|
| `VITE_WS_URL` | `ws://localhost:8080` | `/ws` | URL WebSocket сервера |
Настройки в `client/.env.development` (dev) и `client/.env` (production).
---
## Протокол обмена
### Аутентификация
```json
// → сервер
{ "type": "auth", "login": "alice", "password": "123" }
// ← ответ
{ "type": "auth_result", "success": true }
{ "type": "auth_result", "success": false, "reason": "Invalid login or password" }
```
### Текстовое сообщение
```json
// → сервер
{ "type": "text", "text": "Привет!" }
// ← всем
{ "type": "text", "from": "alice", "timestamp": 1717000000000, "text": "Привет!" }
```
### Файл / изображение / аудио / видео
```json
// → сервер
{ "type": "file", "filename": "cat.png", "mime": "image/png", "data": "<base64>" }
// ← всем (от сервера добавлены from и timestamp)
{ "type": "file", "from": "alice", "timestamp": 1717000000000, "filename": "cat.png", "mime": "image/png", "data": "<base64>" }
```
Клиент определяет тип файла по MIME: `image/*` — картинка, `audio/*` — плеер, `video/*` — плеер, остальное — скачивание.
### Системные сообщения
```json
{ "type": "system", "text": "alice joined the chat" }
{ "type": "system", "text": "alice left the chat" }
```
---
## Функциональность
- **Текстовые сообщения** — логин отправителя, время, ссылки (http/https) автоматически становятся кликабельными
- **Файлы** — любые типы, до 10 МБ (настраивается), base64 в JSON
- **Изображения** — `image/*``<img>`, клик открывает в новой вкладке
- **Аудио** — `audio/*``<audio controls>` + ссылка скачивания
- **Видео** — `video/*``<video>` с controls + ссылка скачивания
- **Голосовые сообщения** — кнопка микрофона, запись через `MediaRecorder`, отправка как файл
- **Уведомления** — звук (Web Audio API) и красная точка на favicon при сообщении на неактивной вкладке
- **Системные сообщения** — подключение/отключение участников
- **Автоскролл** — кастомный тонкий скроллбар
---
## Структура проекта
```
chat/
├── server/
│ ├── config.js # Настройки из env
│ ├── auth.js # Загрузка пользователей, authenticate()
│ ├── clients.js # Управление соединениями, broadcast()
│ ├── server.js # Точка входа, WebSocketServer
│ ├── users.json # Хардкоженые логины/пароли
│ └── package.json
├── client/
│ ├── src/
│ │ ├── App.jsx / .css
│ │ ├── main.jsx
│ │ ├── hooks/
│ │ │ ├── useWebSocket.js # WebSocket + auth
│ │ │ └── useChatMessages.js # Приём сообщений + уведомления
│ │ ├── utils/
│ │ │ ├── blob.js # base64 → Blob URL
│ │ │ ├── linkify.jsx # URL → React-ссылки
│ │ │ └── notify.js # Звук + favicon
│ │ └── components/
│ │ ├── Login.jsx / .css
│ │ ├── Chat.jsx / .css
│ │ ├── MessageList.jsx
│ │ ├── Message.jsx / .css
│ │ ├── MessageInput.jsx / .css
│ │ └── VoiceRecorder.jsx / .css
│ ├── .env # Production настройки
│ ├── .env.development # Dev настройки
│ ├── index.html
│ ├── vite.config.js
│ └── package.json
├── Dockerfile # Многостадийная сборка
├── docker-entrypoint.sh # Auto-restart при падении
├── nginx.conf
├── .dockerignore
├── .gitignore
└── README.md
```