1. Пользователь устанавливает вебсокет соединение с сервером.
2. Пользователь пробует добавить сообщение в чат. Отправляет запрос:
{id: 1, action: 'chat:add', params: {chat_id: 1}}
3. Сервер присылает ответ
{id: 1, error: 'Not authenticated'}
4. Пользователь отправляет
{id: 2, action: 'user:login', params: {email: 'test@me', password: 'qwerty'}}
5. Сервер отвечает
{id: 2, data: {token: '123456'}}
6. Пользователь повторяет пункт 2. Сервер отправляет пользователю успешный ответ, а его собеседника уведомляет новым личным сообщением.
Это грубо. В целом, ты работаешь почти также как и с HTTP. В формате запрос -> ответ. Отличие только в том, что вместе с ответом на запрос, иногда нужно будет уведомлять других пользователей о произошедшем событии.
Формат обмена сообщениями между клиентом и сервером надо придумать самому или выбрать из существующих. Клиент должен как-то различать, когда пришел ответ на запрос, а когда уведомление.