Я бы использовал отсортированный набор, где члены - это идентификаторы сервера WS, а оценка - это отметка времени их последнего "пинга".
Периодически пингуйте каждую WS (например, каждые 10 секунд), обновляя отсортированный набор своим идентификатором. Вы можете использовать скрипт Lua, чтобы получить время с сервера и установить счет участника, чтобы все было красиво и атомарно:
redis.replicate_commands()
local t = redis.call('TIME')
return redis.call('ZADD', KEYS[1], tonumber(t[0]), ARGV[1])
Таким образом, если ваш отсортированный набор называется "wsservers", а идентификатор WS - foo, вы можете вызвать скрипт после загрузки его с помощью EVALSHA <script-sha1> 1 wsservers foo
.
Чтобы вернуть счетчик, все, что вам нужно сделать, - это диапазон отсортированного набора за последний период (то есть 11 секунд) и подсчитать результаты. Вы также можете использовать эту возможность для обрезки старых мертвых серверов. Конечно, сценарий Lua является моим предпочтительным подходом, и он выполняет обе задачи без необходимости фактически отправлять необработанные члены WS по линии вызывающему клиенту:
local t = redis.call('TIME')
local live = redis.call('ZRANGE', KEYS[1], tonumber(t[0])-11, '+inf')
redis.call('ZREMRANGEBYSCORE', KEYS[1], '-inf', tonumber(t[0])-11)
return #live