使用HTML5,WebSockets,nodejs和socket.io構建實時游戲

jopen 12年前發布 | 73K 次閱讀 HTML5 WebSocket 開發 WebSockets NodeJS

    想象一下在網絡上玩游戲只需要簡單地登錄,不需要本地安裝,不需要任何許可證,在瀏覽器或者手機中的多人游戲可以斷線重連--這基本上就是“云游戲”了。好吧,這聽起來挺俗套了,但是我們接下來就能見識到這些了,而且比我們想象的更好更快!

    我們先列出一些概念建立真正有潛在意義的東西我們想要做是:

  • 發布常見的瀏覽器上展現的游戲

  • 在不同瀏覽器(桌面版或者移動版)上控制游戲

  • 管理控制器與游戲之間的通知

  • 確保不需要任何的安裝,即使作為瀏覽器插件

  • 估計涉及到的延時

初始調查研究以及選擇

    Nodejs 擁有高并發特性,是個 JavaScript 框架,因此是基于函數式或者事件編程的。這聽起來很棒,但是有較陡的學習曲線。socket.io 實現的 WebSockets 運行得很好,便于管理。

    EventMachine 同時也管理著使用事件觸發的 I/O 的高并發,對于高并發這應該是一個理想的選擇,但怎么才能讓 WebSockets 更容易管理呢?

    簡單地根據一些關于 nodejs 和我們調查研究的新玩意兒判斷,我們選擇了 nodejs。

    以下是我們用到的一些節點模塊:

  • Socket.IO - 很明顯的 WebSockets 選擇
  • Express - 這是我們對用戶界面的選擇。我們本可以使用 Rails 程序,但是殺雞焉用牛刀?
  • Jade - HTML 模版
  • Redis - 數據分發

就此行動

    我們需要構建的是一個能夠給我們想要數據并且很有趣的東西,所以,我們決定開發一個叫 “Tapit” 的游戲。

    Tapit 是一個舞池,在這里你能通過點擊一個唯一的URL然后輸入你的昵稱加入游戲,隨后你可以看到代表你的卡通人物出現在舞池中,在你的移動瀏覽器中也會出現控制器 - 有4個動作可以改變圖像令你的卡通人物舞動起來。這便是創建了一個“集中交互式游戲”,玩家能在舞池前看到他的卡通人物在舞蹈,并播放著他的調調!這是一個很有潛力的簡單應用。

    所以,我們開始建立服務器節點以及節點模塊,并且在服務器上安裝了 Redis 以最大程度利用 Redis 的分發優勢。

    需要安裝節點,npm 以及節點模塊,可以閱讀以下鏈接:nodejs and  npm

配置 socket.io,express 以及 redis

我們建立服務器節點并可如下配置:

HOST = "localhost",
PORT = "3001"

var express = require('express')
 , app = express.createServer()
 , redis = require('redis')
 , io = require('socket.io').listen(app);

const DB = redis.createClient();
io.set('log level', 1); // reduce logging

app.use(express.bodyParser());
app.use(express.static(__dirname + '/public'));
app.set('view engine', 'jade');

app.listen(PORT);

我們還需要保持 Redis PubSub通道是打開的,我們可以這樣做:

io.sockets.on('connection', function(socket) {
  const subscribe = redis.createClient();
  const publish = redis.createClient();

  socket.on('publish', function(channel, data) {
    publish.publish(channel, data);
  });

  socket.on('psubscribe', function(channel) {
    subscribe.psubscribe(channel);
  });

  subscribe.on("pmessage", function(pattern, channel, message) {
    socket.emit('message', { channel: channel, data: message });
  });
});

創建一個新的舞池

    為了創建一個新的舞池,我們需要調用 '/games/new' 這個鏈接來顯示,這將創建一個舞池,并準備好客戶端代碼并偵聽“新加舞者”或者“動作改變”的事件。

開始游戲

    為了使卡通人物出現在舞池中,用戶需要鍵入由移動瀏覽器生成的唯一舞池的 URL,然后將出現一個輸入你的昵稱的界面,這樣你便能在舞池中定義自我了。

正式開玩

    一旦你加入游戲后,你講看到你的卡通人物出現在舞池中。

    同時,你將在你的移動瀏覽器中看到四個控制鍵。你可以點擊任何一個使得你的卡通人物在舞池中舞蹈。

    這是客戶端如何用JS進行動作控制的:

$("#subscribe").submit(function() {
  socket.emit('psubscribe', $('#subscribe #channel').val());
  return false;
});

$(".action").click(function() {
  socket.emit('publish', 'game.#{gameid}.action.' + $(this).data('action'),
  JSON.stringify({ nick: "#{nick}", ts: Date.now() })
);

    WebSockets 將為特定游戲發布出控制事件,當 nodejs 接受到事件以后,將通過 Redis PubSub 分發出去。只要有監聽器連接著,他們就都會收到事件通知。由于監聽器本身就是WebSockets,他們將會在網頁上接收到推送的通知。

性能 - 延時與并發

    我們在各種類型的網絡環境中進行了測試,如 WiFi,3G 甚至是 Edge 網絡。最壞的場景情況是 Edge 網絡,我們發現有 200ms 的延時--這可能還是還是可以接受的。

    當我們測試并發的時候,我們能輕松地達到一百個舞者同舞的規模,現在最大的問題就是我必須為每一個用戶打開一個 redis 客戶端。所以我需要解決這個問題,其他的問題便是服務器端的 “Too many files open” 異常。這不是一個與節點相關的問題而是與配置有關的問題。

Github repos

    已將該游戲更新到了github http://github.com/joshsoftware/tapit

至此我們還要做些什么?

    這只是個開始,我們接下來要在web上構建一個多人游戲。這將帶來規模以及延時的限制。

    原文地址 , OSChina.net原創編譯

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!