Как написать код веб-сокета javascript, который будет работать в chrome и в node.js?

Ответ на этот вопрос сводится к двум вещам: 1) будет ли проще использовать BOSH или веб-сокеты, учитывая ограничения node.js, и 2) как мне структурировать код, чтобы один и тот же файл javascript одинаково хорошо работал в браузер, как в Chrome (или другом браузере). Кратко описать проблему сложно.

Настоящая проблема заключается в желании, чтобы код одинаково хорошо работал в браузере, как и в node.js, но при этом имел внешние зависимости.

Фон

У меня возникла идея, что я хочу делать небольшие проекты javascript для развлечения. Я называю эту идею jsFun, и основная идея заключается в том, что я могу потратить от 30 минут до часа, делая что-то веселое и делясь этим с друзьями.

Я начал с того, что посмотрел, смогу ли я написать Tetris за час, используя только Notepad++, Chrome и Dropbox. У меня не получилось, но было весело.

Для меня «веселье», вероятно, означает игру, и это, вероятно, означает мультиплеер. Эскиз обратной стороны салфетки выглядит так:

  • Я могу вносить изменения с любого компьютера и отправлять их через Dropbox. (Проверьте!)
  • Я могу использовать общедоступный URL-адрес Dropbox для обслуживания статических страниц. (Проверьте!)
  • Веб-клиенты могут использовать веб-сокеты HTML5 или BOSH для маршрутизации сообщений через сервер чата node.js.
  • Скрипты игрового сервера также могут подключаться к серверу чата и реализовывать некоторую игровую логику.
  • Скрипты игрового сервера могут быть запущены либо в браузере, либо в node.js.

Вот отличный пример использования веб-сокетов HTML5 для связи с сервером чата node.js: http://html5demos.com/web-socket

Допустим, я делаю многопользовательские крестики-нолики. В моем проекте нужно 3 части:

  • Скрипт игрового клиента — это javascript, который запускается в браузере и отображает игру для пользователя.
  • Скрипт чат-хаба — это чат-сервер, который передает сообщения между игровыми клиентами и игровым сервером. Он работает как процесс node.js.
  • Скрипт игрового сервера — этот скрипт можно запустить в браузере для тестирования и отладки или в node.js.

Теперь, чтобы сделать крестики-нолики, я удостоверюсь, что сервер чата работает, создам сценарий игрового сервера и сценарий игрового клиента и открою три веб-браузера - два клиента и один сервер. В этот момент я могу использовать потрясающие инструменты отладки Chrome для решения любых проблем, делать обновления в блокноте ++ и обновлять браузеры как сумасшедшие в течение 30–60 минут. И, возможно, у меня есть рабочая игра на тот момент.

Это усложняющий шаг: тот скрипт игрового сервера, который я запускал в браузере, теперь я хочу запустить из node.js. На самом деле, я хочу, чтобы чат-сервер контролировал мой каталог сценариев сервера Dropbox на наличие изменений и автоматически запускал эти сценарии.

Node.js использует модули CommonJS, которые браузер не может загрузить. Я думаю, что могу использовать RequireJS и теоретически загружать код в любой среде, но тогда проблема заключается в том, что браузер и сервер будут использовать разные библиотеки для работы с веб-сокетами — как мне сделать код, который работает в любом случае? Можно ли использовать веб-сокеты, поскольку кажется, что это постоянно меняющийся стандарт, и, возможно, я не могу зависеть от сервера веб-сокетов node.js для работы в долгосрочной перспективе.

Единственный доступный сервер веб-сокетов для node.js, похоже, находится в стадии разработки: https://github.com/miksago/node-websocket-server

Может быть, мне следует использовать более зрелый API, такой как BOSH?

Кроме того, клиент websocket также не встроен в node.js, поэтому мне пришлось бы использовать это: (Как новый пользователь stackoverflow, я не могу нормально вставить ссылку. Это https://github.com/ pgriess/узел-websocket-клиент)

Мне пришлось бы столкнуться с проблемой, что мой код игрового сервера, выполняющий подключение веб-клиента к серверу чата, будет использовать другие библиотеки в среде выполнения node.js, чем в среде браузера Chrome.

И, может быть, вместо использования require.js я мог бы использовать стандартные скрипты javascript в браузере и использовать node.js vm.runInContext — похоже, я мог бы настроить глобальную переменную с аналогичными функциями перед вызовом скриптов, и это будет работать в значительной степени точно так же в node.js или браузере, используя стандартный код javascript.

Повторная формулировка вопроса

(Предполагая, что я заранее настроил глобальную среду в любом случае, чтобы предоставить скрипту общий интерфейс.) Есть ли для меня практический способ написать файл javascript, который обращается к функциям, подобным веб-клиенту, который может выполняться в браузер или в node.js?


person Michael McHenry    schedule 09.01.2012    source источник
comment
Кажется, у меня сейчас работает эта версия. Модули requireJS достаточно приятны на вкус и работают как в браузере, так и в node.js. Не потребовалось слишком много усилий, чтобы правильно внедрить зависимости, чтобы клиенты браузера и node.js выполняли один и тот же код. Кроме того, socket.io реализовал клиент веб-сокетов на стороне сервера (github.com/LearnBoost/socket.io-client), который, кажется, работает.   -  person Michael McHenry    schedule 10.01.2012
comment
Я уверен, что requireJS — лучший способ обмена кодом между браузером и node.js. Я просто не уверен, что делаю ставку на правильную лошадку с socket.io. Причина, по которой я мучил себя этим, заключается в том, что пример веб-сокетов HTML5 настолько прост, что вся эта дополнительная сложность кажется ненужной.   -  person Michael McHenry    schedule 10.01.2012


Ответы (1)


Если для запуска веб-сокетов требуется немного усилий, не бойтесь, так как награда стоит гораздо больше, чем усилия.

До веб-сокетов все действительно основанные на браузере предложения полагались на то, что браузер постоянно опрашивает сервер, что является большой нагрузкой как для браузера, сети, так и для сервера.

Даже простое сообщение «привет» в системе, основанной на HTTP-опросе, может потребовать обработки килобайт данных.

В веб-сокетах количество накладных расходов в худшем случае составляет около 15 байтов.

Другое дело, что веб-сокеты управляются событиями, поэтому ваш браузер может бездействовать или выполнять другие задачи, пока не произойдет фактическое событие связи.

Что касается вашего вопроса о том, чтобы код хорошо работал на переднем и заднем концах, это будет вопрос создания ваших классов javascript модульными и использования функций типа require() на стороне сервера и, возможно, моделирования той же функции на клиенте сторону для внедрения создаваемых вами сценариев.

Есть много демонстраций, которые можно загрузить и поработать с ними, так что, как и в любой новой области кодирования, просто прыгайте и запачкайте руки. Скоро это будет иметь смысл.

person Dr Clue    schedule 10.01.2012
comment
Мои руки сильно испачкались. node.js использует формат модуля commonJS, который плохо работает в браузере. На самом деле я рассматривал возможность взлома узла, чтобы иметь возможность обрабатывать javascript в стиле браузера, используя vm.runInContext, но я попробовал RequireJS, и это было достаточно хорошо. - person Michael McHenry; 11.01.2012
comment
Настоящая боль была в веб-сокетах. У меня был бы более быстрый запуск, если бы я выбрал BOSH, потому что стандарт устоялся. Я перепробовал как минимум 5 библиотек, пока не получил то, что хотел. Большая часть информации, комментариев и руководств указывает на библиотеки, которые начинают ржаветь, но если вы посмотрите, вы найдете ответвление, которое может быть более современным, но также содержит ошибки. Я попробовал socket.io, потому что он обещал подключиться по любому протоколу, и мне понравился его API, но, хотя я достаточно легко запустил клиент веб-сокета браузера, я не смог заставить работать клиент веб-сокета узла. - person Michael McHenry; 11.01.2012
comment
Наиболее зрелая кодовая база с рабочими реализациями сервера и клиента, которые принимают стандартные веб-сокеты браузера, выглядит следующим образом: github.com/einaros/ ws Однако этот проект лучше задокументирован, поэтому я выбрал его: github.com/Worlize /WebSocket-узел - person Michael McHenry; 11.01.2012
comment
Теперь это работает. Я чувствую себя глупо, отвечая по существу на свой вопрос, но это заняло много времени, с большим количеством проб и ошибок. :-/ - person Michael McHenry; 11.01.2012