Как организовать викторину с таймерами на websocket на сервере?
я хочу написать викторину nodejs. на клиенте пользователи подключаются по websocket.io к серверу. викторина у меня работает так, создается раунд на 10 вопросов в который попадают два пользователя. на каждый вопрос дается минута, через минуту он сменяется на другой, или сменяется как кто-то из пользователей ответит на вопрос. после 10 вопросов считаются очки и признается победитель.
Я не понимаю как ответить себе на вопросы:
1) как создать счетчик времени на сервере? я понимаю что есть setinterval, но этот счетчик будет на весь сервер, а на нем может быть 20 викторин с 40 игроками например. не понимаю, мне надо создать 20 счетчиков? или 1 счетчик смотрит, не закончился ли вопрос в каждой 20 викторине? и как технически это написать, именно код?? я не могу понять
2) если я буду хранить ответы на вопросы в памяти сервера, а толко после окончания викторины записывать данные в бд, то как мне их хранить? в json объекте? или мне нужно внешнее хранилище и почему?
3) как физически выглядит сервер, могу ли я просто в одном потоке все викторины держать? или надо что-то сложное делать, кластер / воркеры, упускаю ли я какой-то аспект?
если у вас одновременно будет небольшое количество викторин и пользователей, ну скажем до 1000 (число взято с потолка и зависит от многих факторов), то вам вообще можно не париться об архитектуре и реализации, пишите как видите, в процессе приобретете бесценный опыт и понимание где вы накосячили как в архитектуре так и в реализации (коде). После того как несколько раз перепишите все с нуля можете претендовать на юниора фулстак))))
Когда досконально разберетесь с этим, поймете и усвоите, увидите минусы и плюсы выбранных подходов и стека технологий, приходите сюда, и задавайте уже конкретные вопросы, с примерами кода и описанием выбранной/придуманной вами архитектуры, просите совета как сделать лучше, спрашивайте (если не найдете в интернете сами) какие есть альтернативы выбранному вами подходу и в чем их плюсы/минусы, изучайте то что вам посоветуют, составляйте свое мнение и выбирайте тот путь который вам понравится больше .
Они (правильные вопросы) к тому моменту а вас точно появятся.
Роман, нет, я ведь задал конкретные вопросы. экспресс тут ни к чему, мне нужно понять, как мне физически создавать таймеры на каждую викторину из моего вопроса. я не создам ведь 1000 таймеров на 1000 викторин для 2000 пользователей? и как мне организовать хранилище под это
naruto3333, вот вам 1 из множества вариантов:
Создавайте таймеры на клиентах, и по истечении заданных таймаутов запрашивайте данные у сервера (по http или ws) а на сервере просто ведите контроль времени по временным меткам (timestamp-ам).
naruto3333, проблема вашего вопроса в том, что он очень общий, на каждый пункт можно придумать десятки принципиально разных реализаций, при этом требующих различных архитектурных подходов. Ответить конкретикой на ваш вопрос нельзя, а если даже сделать решение, не факт что оно попадет в зону вашего видения и не будет вами отвергнуто. Вот скажите, оно мне (или кому еще) надо? Писать достаточно много кода чтобы вы потом либо сказали что не подходит/не разобрались, либо начали бомбить в комментах кучей уточняющих вопросов и просьб по типу "Так мне не подходит, нужно по другому, дайте мне ....?" или "а вот тут не могли бы вы помочь привязать слона к банану?"
Роман, спасибо! интересно, но получается что если никто из участников не ответит на вопрос (пропадет интернет у обоих), то викторина никогда не завершится? но она технически должна быть завершена через 10 минут
Роман, спасибо, но мне нужен не код, а понимание как его написать. архитектурный подход тут один - это событийная модель, но я не сталкивался с таким, чтобы сервер был инициатором событий для клиентов. едиственное понимание, как сделать сервер инициатором - это повесить ему setinterval, чтобы он отдавал пользователям ежесекундно например статус о текущем вопросе викторины. но я чувствую что-то неправильное в том, чтобы создавать 1000 setinterval, в каждом из которых происходит 1000 коллбеков ежесекундно для каждого пользователя, из-за чего могут вообще происходить погрешности во времени в силу однопоточности nodejs
naruto3333, нет не получается. На сервере вся ваша викторина это просто данные в БД привязанные к определенному ID игры и простейший CRUD для доступа к ним. Если клиенты отвалились и никогда не зашли в викторину то просто эти данные надо подчистить (или оставить как незавершенные игры для статистики). Подчистить можно по крону (отдельным приложением, запускаемым например раз в сутки) или уже таймеру на самом сервере (тут сложностей не возникнет я думаю).
naruto3333, а вот это уже пример (достаточно запутанный и лапшеобразный) событийной модели с ws транспортом двухстороннего обмена данными (событиями) между клиентами и сервером (не смотрите все то что там связанно с кластерами, смотрите то что связанно с вэбсокетами, а лучше начните распутывать с кода клиентской части и затем уже лезьте в app.js ))))
Сразу предупреждаю, это в общем то велосипед, для таких целей принято использовать не свои самописные модульки а что то типа socket.io с его достаточно широкими возможностями
Роман, ура! теперь до меня дошло )) действительно все просто данные в базе, меняющиеся по требованию пользователя. и если один ответит на вопрос, то и оппоненту придет по вебсокету уведомление! таймер это иллюзия ))