2016-09-24 28 views
1

我的代碼依賴於在進行之前設置的其他代碼。在繼續之前,如何限制dom等待從服務器發送的東西?我已經嘗試了一段時間的聲明,並且最終導致「調用堆棧超出」異常。我也嘗試過setTimeOut,而render()將起作用,但我仍然會在render中得到一個異常,說明selfId還沒有定義。我怎樣才能解決這個問題?socket.io:如何確保設置值

舉例: 客戶:

<!DOCTYPE html> 
<html> 
    <head> 
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> 
     <script src="https://cdn.socket.io/socket.io-1.4.5.js"></script> 
     <link href="client/main.css" rel="stylesheet"</link> 
    </head> 
    <body> 
     <div id="game"> 
      <!--GAMEBOARD--> 
      <canvas id="ctx"></canvas> 
      <!--CHATUI--> 
      <div id="chat" class="chat"> 
       <div id="messages" class="messages"> 
        <div>Welcome to Simon's Game Server</div> 
       </div> 
       <input id="chatinput" class="chatinput"></input> 
      </div> 
      <div id="fps"></div> 
      <!--ADDITIONALUI--> 
     </div> 
     <script> 
      var socket = io(); 
      //game loop 
      var lastTime; 
      function gameLoop() { 

      } 

      //init 
      var selfId = null; //How do i set this variable when the first user connects? This is my question 
      socket.on('setSelf', function (data) { //this is my attempt, but it is not working for the first user. 
       console.log('Setting selfId to: ' + data.id); 
       selfId = data.id; 
       gameLoop(); 
      }); 

     </script> 
    </body> 
</html> 

服務器:

var express = require('express'); 
var app = express(); 
var server = require('http').Server(app); 
var port = 1338; 
var io = require('socket.io')(server); 

//routes 
app.get('/', function (req, res) { 
    res.sendFile(__dirname + '/client/index.html'); 
}); 
app.use('/client', express.static(__dirname + '/client')); 

server.listen(port); 


var UNIQUEID = 0; 
io.sockets.on('connection', function (socket) { 
    socket.myid = UNIQUEID; 
    UNIQUEID++; 
    socket.emit('setSelf', { id: socket.myid }); 
}); 
+1

你爲什麼不在'setSelf'裏面調用'gameLoop();''? – monkeyinsight

+0

我嘗試了這一點,但是當我構建項目並首先打開服務器並嘗試在控制檯上回顯selfId時,它會顯示爲未定義。 爲什麼? – simon

回答

0

在Javascript中,你不能 「等待」 或 「休眠」,直到事情發生。它不這樣工作。相反,您註冊了某種事件處理程序,並在發生這種情況時觸發代碼。你的情況,你可以是這樣做的:

var selfId = null; 
socket.on('setSelf', function (data) { 
    selfId = data.id; 
    // don't call gameLoop until you get here and selfId is set 
    gameLoop(); 
}); 

function gameLoop() { 
    render(); 
    //.... 
    playerState(); 
    // 
    //etc .... 
    // 
} 

此外,在服務器上,你不應該覆蓋socket.id作爲socket.io鑄造自己的ID,並使用在其自己的看家。如果您想在socket對象上存儲某個屬性,我建議您創建自己的唯一,無衝突的屬性名稱,例如.myId

+0

向我解釋爲什麼如果我將console.log(selfId)放在selfId = data.id後面,客戶端上的控制檯顯示爲0.然而,當我在客戶端上時,如果我輸入控制檯selfId, Uncaught ReferenceError:selfId未定義(...)??? – simon

+0

我試過這段代碼,並且仍然在控制檯上,如果我嘗試回顯selfId,我會得到該引用錯誤。 – simon

+0

@simon - 您必須向我顯示導致該錯誤的確切代碼,因爲我在回答中的代碼不會導致該錯誤。我的猜測是你做了與我在這裏展示的不同的東西。另外,我注意到你正在覆蓋服務器上的'socket.id'。這是一個非常糟糕的主意。 socket.io使用'socket.id'來自己使用。如果要在服務器端套接字對象上存儲屬性,請創建不衝突的不同屬性名稱,例如「socket.myId」。 – jfriend00