Node.js UDP для многопользовательской игры в режиме реального времени
Я создаю в режиме реального времени многопользовательскую браузерную игру, используя node.js. На данный момент у меня клиент отправляет пользовательский ввод на сервер логики игры через socket.io и моментальный снимок игрового мира, отправленного обратно клиенту для рендеринга.
Ниже приведена упрощенная версия кода. Можно ли использовать UDP для отправки данных с браузера на сервер и наоборот? Я знаю, что node.js имеет UDP-модуль, но я не уверен, как его реализовать таким образом.
Любая помощь будет оценена по достоинству. Спасибо.
Сервер:
var server = http.createServer(handler).listen(8888);
var iosocket = io.listen(server);
// request/response handler
function handler(req, res){
...
}
iosocket.sockets.on('connection', function(socket){
console.log("[x] Socket listener started");
socket.on('msg', function(data){
console.log( " [-] incoming message);
});
});
...
iosocket.sockets.emit("message", msg);
Клиент:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
socket.on('connect', function(){
console.log("connected to server");
});
socket.on('message', function(message){
console.log('received message');
});
</script>
</head>
<body>
<canvas id='canvas' width="400" height="400">Canvas</canvas>
</body>
</html>
Ответы
Ответ 1
Как правило, браузеры не поддерживают соединения UDP. В частности, некоторые браузеры. Google Chrome имеет сокет api:
http://developer.chrome.com/trunk/apps/socket.html
[2012/10/29 Отредактировано как сокет больше не экспериментальный - PhilH]
Возможно, вы также можете использовать API-интерфейсы сокетов из собственных клиентских интерфейсов (не уверен, только гадание).
Если вы собираетесь делать что-то в реальном времени в браузерах в ближайшем будущем, Websockets, вероятно, лучше всего, но это только TCP.
Что касается ваших комментариев по UDP и скорости TCP, UDP всегда будет быстрее. TCP предлагает гарантию на поставку и доставку (это означает, что вы можете повторять попытку и удерживать другие пакеты до тех пор, пока потерянный пакет, наконец, не достигнет своего пункта назначения), тогда как UDP только promises отправит его один раз, не заботясь о том, что с ним происходит потом. UDP будет отправлять пакет только один раз, и вам нужно выяснить, потерялся ли он. Когда/если вы получаете много UDP-пакетов, если дело касается заказа, вам нужно закодировать это в своей полезной нагрузке, чтобы понять это.
В общем, UDP будет отлично подходит для пакетов, где не хватает нескольких, как правило, не имеет значения, и на самом деле имеет значение только последний пакет. Обычно игра может использовать поток TCP, в котором важны заказы и гарантированные вопросы доставки (важный материал), а также потоки UDP для перемещения объектов и т.д. (Где только последняя позиция действительно имеет значение, и если одно обновление потеряно, это не имеет значения, если каждый пакет содержит полную позицию [вместо дельта, где все пакеты имеют значение]).
Для вашей собственной игры я предлагаю сначала внедрить ее в TCP, а затем, когда у вас есть больше опыта, вы можете попробовать переместить критически важные вещи (где порядок и потерянные пакеты меньше) в отдельные потоки UDP. Есть много проектов, которые потерпели неудачу, потому что люди сначала начали с UDP, а затем попытались выполнить привязку к заказам и гарантиям доставки поверх этого, эффективно пытаясь переопределить TCP. Вот почему делать это наоборот имеет смысл.
Ответ 2
Приложение в реальном времени, как правило, получает обновления данных не менее 30 Гц и менее 10% дрожания. TCP/IP является надежным, но не может отправлять периодические обновления с такой скоростью, без какого-либо дрожания. Это связано с тем, что TCP поддерживает связь и подтверждает, что обеспечивает надежную передачу, которая мешает быстро отправлять плавные обновления. UDP - это более простой протокол, в котором данные сокета являются огнем и забываются. Это само по себе проблема, но эта проблема легче преодолеть, чем плохой джиттер TCP/IP. По моему опыту UDP - это единственный путь вперед и почему приложения реального времени используют его внутри протоколов, таких как RTP, используемых в VoIP.
Веб-сокеты - ложная надежда, так как это протокол TCP. Я использую пользовательские сокеты UDP, где отправитель и получатель поддерживают порядковый номер, и который может сказать вам, что пакеты потеряны, дублированы или несовместимы, все проблемы в сетях глобальной сети. Найти способы использования UDP и измерить входящие пакеты данных для измерения производительности.
Ответ 3
var server = require('http').createServer();
require('dgram-browserify').listen(server);
server.listen(8080);