Протокол сообщений: типы событий на JSON
Договариваемся, в каком формате клиент и сервер обмениваются сообщениями.
Протокол сообщений — соглашение о структуре каждого сообщения: какие поля есть и как по ним понять, что это за событие.
Зачем нужен протокол
По одному каналу ходят разные события: сообщение чата, вход пользователя, набор текста («печатает...»), ошибка. Если слать просто текст, приёмная сторона не разберёт, что это. Поэтому каждое сообщение оборачивают в конверт — JSON-объект с обязательным полем type.
Единый конверт
Договоримся: каждое сообщение — объект с полем type и полезной нагрузкой:
{ "type": "chat", "user": "anna", "text": "привет" }{ "type": "join", "user": "ivan" }{ "type": "typing", "user": "anna" }{ "type": "error", "message": "комната переполнена" }Получив сообщение, обе стороны смотрят на type и решают, что делать. Это как switch по типу события.
Маршрутизация по типу — чистая логика
Диспетчеризация по полю type — обычная работа с объектами, сервер не нужен. Покажем разбор на чистом JS:
function describe(raw) {
const msg = JSON.parse(raw);
switch (msg.type) {
case "chat": return msg.user + ": " + msg.text;
case "join": return "-> вошёл " + msg.user;
case "typing": return msg.user + " печатает...";
default: return "неизвестно: " + msg.type;
}
}
console.log(describe('{"type":"join","user":"ivan"}'));
console.log(describe('{"type":"chat","user":"anna","text":"привет"}'));
console.log(describe('{"type":"ping"}'));Вывод:
-> вошёл ivan anna: привет неизвестно: ping
Как работает под капотом
WebSocket сам по себе передаёт лишь байты — он не знает про чат, входы и ошибки. Весь смысл задаёт ваш протокол поверх него. Поле type — точка расширения: добавили новое событие — клиенты, которые его не знают, просто попадут в default и проигнорируют, а не сломаются. Поэтому правило: всегда обрабатывайте неизвестный type безопасно.
Частые ошибки
- Слать разные форматы для разных событий. Единый конверт с
typeупрощает и клиент, и сервер. - Падать на неизвестном
type. Разные версии клиента и сервера должны уживаться — неизвестное игнорируйте. - Не валидировать входящие данные на сервере. Клиент может прислать что угодно; проверяйте структуру, прежде чем доверять.
Итоги
- Каждое сообщение — JSON-конверт с обязательным полем
type. - Обе стороны маршрутизируют обработку по
type, какswitch. - Неизвестные типы игнорируйте безопасно — это даёт совместимость версий.
- Сервер обязан валидировать входящие данные, не доверяя клиенту.