Ух, так у все управление сессиями базируется на том, что клиент будет слать запросы в рамках одного соединения?
Достаточно чуть дольше думать над ходом, браузер закрывает соединение и начинаются глюки потому что на сервере началась новая игра, а клиент об этом не знает…
Да, открытое соединение служит как идентификато, если есть поддержка keep-alive браузер будет слать все get ajax запросы через 1 соединение.
Насчет таймаутов, в заголовках это — Keep-Alive: timeout=25, max=100, если в течение 25 секунд не будет никаких дествий, бразурер должен закрыть соединение, но в браузерах свои дефолтные настройки, и этот заголовок они просто игнорирует, в FF к примеру таймуат — 115 секунд, а это 2 минуты, я думаю хватит подумать.
вот, кстити табличка(тесты не мои):
Opera 11.11 – 120 seconds
Chrome 13 – at least 300 seconds (server closed after 300 second timeout)
IE 9 – 60 seconds
Firefox 4 – 115 seconds
Если так случилось, что сторона пользователя закрыла соединение(корректно), процесс просто выйдет из цикла, и новая игра не начнется, и при этом поле тоже не очистится, получается когда вы делаете ход, вот тогда, и иннициализируется новая игра, но при этом на старом поле(оно ведь не очищено).
При такой реализации, если браузер закрывает соединение, пользователь никак не узнает, что продолжить это игру ему не удастся, это связано с тем, что на стороне пользователя, нет события закрытия соединения.
Проще вместо всей этой фигни с take_socket и прочим просто завести N процессов, каждый из которых будет accept'ить один и тот же сокет и при успехе просто спавнить еще один такой же, а основную работу продолжать в себе самом. Таким образом мы гарантируем, что слушающий сокет не будет простаивать пока процесс инициализирует клиента.
Если я правильно понял, Ваша модель только увеличит производительность приема клиентов, из-за того, что мы выносим accept'ы в разные процессы, а главная причина почему я использовал фигню с take_socket, это для того, чтобы избежать гонок между spawn() и controlling_process().
да, вы правильно поняли, это позволит подключаться одновременно большему числу клиентов. Я понял, что take_socket используется, чтобы избежать RC, просто предложил вариант проще. Кстати, а почему вы предпочли сырую реализацию реализации через OTP?
Предпочел реализацию без OTP, наверное главной причиной является недостаточное знание фреймворка.
Я запомню вашу модель сетевого взаимодействия, это будет действительно проще и логичней.
получилась гомоку с уменьшенной доской. до рэндзю не хватает ещё ста пятнадцати клеток и турнирных правил. очень нравится эта игра
на 3.6 уже не хватает доски (мне) выстроить вилку :)
попробую реализовать полную версию, давно хотел потрогать эрланг; спасибо за предельный стиль изложения
возможно где-то есть логическая ошибка, алгоритм 3.6 сделал неверный ход, вилки не было…
или «бот играет достаточно хорошо в пределах [0.5, 1]», но более 1 уже недостаточно хорошо? сел за код, разбираюсь…
на 3.6 он должен пресекать(защитная стратегия) все ваши ходы, насчет ошибки, возможно бот сыграл недостаточно эффективно для той игровой ситуации, но бот только оценивает выгоду куда поставить, в той ситуции значит алгоритм посчитал, что выгодно поставить именно там.
Cowboy + websockets тут идеальны будут.
Писать на Erlang без OTP — довольно бессмысленно.
Обычно при появлении в коде в чистом виде оператора отсылки сообщения ("!") и/или функции «spawn» (особенно без link) говорит, что что-то тут не так…
OTP — это не фреймворк, это скорее стандартная библиотека плюс архитектурные рекомендации, которые учитывают знания и опыт разработчиков. Поэтому писать можно и без, только зачем изобретать велосипед и собирать грабли, когда можно это всё обойти?
А если интересно более глубоко опробовать Erlang, то этот же проект, только на OTP и Cowboy с вэбсокетами будут отличным продолжением. ;-)
всё обойти
На этапе обучения — чтобы лучше понимать саму OTP. Только делать это надо осознано, а не с целью, сделать свое с 0 и лучше. Рано или поздно, возникают ситуации, которые уже нельзя обойти. Это редкость, но досадная. Лучше сразу понимать как и что устроено.
Продолжение: +1.
Может генерировать на сервере рандомный GameId и отправлять его клиенту в куку?
Тогда при внезапном рестарте сессии его можно опознать и вернуть в игру.
Лучше даже не куку а с server.my/newgame/ редиректить на server.my/join// это ползволит 1) прозрачно балансировать нагрузку 2) сразу очевидно как сделать многопользовательскую версию и делиться ссылкй с другом.
Это следующий этап.
Потом можно сделать номера всем играм, выставить в список игр и любой желающий сможет зайти посмотреть на игру других людей.
А когда человек присоединяется к игре, он заходит на site.my/game/new оттуда с кукой уходит на site.my/game/[game_id]. В этом случае кука подтверждает его право участвовать в игре, а не просто смотреть.
Сидел разбирался с кодом. Фиксил баги. И всё это время меня не отпускало двоякое чувство, что автор с одной стороны очень силён в недрах эрланга и http. С другой стороны увлечён демосценой. А с третьей стороны — дилетант в программировании. 8-\ Какая-то гремучая смесь прям получилась
Крестики-нолики на Erlang