Здравствуйте.
Пишу чат на php 7.2 + websocket + workerman, сервер apache.
Вопрос в том, как лучше отправлять сообщения на workerman (через ajax или через уже открытый websocket)?
Я, конечно же, сначала выбрал через websocket.
Почему не уверен в этом выборе? На стороне workerman нужно понять кто отправил сообщение, а в само сообщение добавлять эту информацию не хочу (в целях безопасности, так как на фронте можно добавить что угодно). Соответственно определить отправителя можно при ajax запросе на сервер (там мы к сообщению дописываем отправителя и по TCP переправляем сообщение на workerman) либо на workerman'е, где в памяти лежит актуальный список пользователей (в виде многомерного массива) с их инфой и открытыми соединениями.
Если пользователей мало, допустим до 1000, то поиск в этом многомерном массиве по id открытого соединения не займёт много времени и ресурсов. А если пользователей 100000 или больше?
Что в итоге будет быстрее и менее затратно по ресурсам?
Действительно, это хороший вариант.
Убрал из массива пользователей ссылки на подключённые соединения. Вместо этого добавил в $connection->user_id id авторизованного пользователя (если такой есть).
Websocket использую как индикатор, что "на сервере поменялось", пересылая минимум информации. С клиента наверх через ws ничего не отправляю. Клиент понимает, что надо дернуть API, имеет при себе сессионные ключи и шлет полноценный запрос. Иначе путаница с данными. У некоторых клиентов ws не работает и надо заменить на другой метод. Основная логика "дернуть API и поменять состояние клиента" остается неизменной.
Подход имеет право на жизнь в личных кабинетах, списках заказов и т.п. не слишком быстро обновляемых данных. WS соединение висит, почти не потребляя трафика и отправляет числа для индикаторов кол-ва заказов.
Делал многопользовательскую игру с браузерными клиентами. Преимущество ajax - гарантия протокола запрос-ответ, проще поддерживать консистентность. С websocket вы пуляете в воздух, вы не знаете принято сообщение или нет, не знаете какое принято раньше, не знаете состояние принимающей стороны. В отсутствии гарантий консистентности сложней прописывать логику. Во всех остальных аспектах websocket лучше - современней, быстрее, асинхронней, непрерывней и при этом ресурсно дешевле. В результате делал на websocket, надстраивал текстовый протокол, вкладывал и парсил метаданные на сервере и клиенте для синхронизации состояния.