2013-10-09 197 views
0

我已經通過websockets在此鏈接「http://www.flynsarmy.com/2012/02/php-websocket-chat-application-2-0/」的幫助下製作了一個聊天應用程序。儘管它在我自己的開發服務器上運行良好,但是當我將其託管在我公司的amazon ec2服務器上時,它顯示錯誤: 「Firefox無法在ws://外部ip上建立與服務器的連接以獲取amazon:port /「WebSockets無法在亞馬遜ec2環境中工作

我在執行服務器文件時嘗試將客戶端連接到服務器和服務器的內部IP用於亞馬遜時正在使用服務器的外部IP。我還在ec2中放置了一個轉發規則,使我的端口可以在tcp和udp中被訪問。

我也檢查了我的亞馬遜服務器的ELB,沒有ELB適用於我的服務器。

它仍然無法正常工作。這是我的服務器文件的代碼的一部分,其中創建套接字並且客戶端正在連接。

if (isset($this->wsRead[0])) return false; 

    if (!$this->wsRead[0] = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) { 
     return false; 
    } 
    if (!socket_set_option($this->wsRead[0], SOL_SOCKET, SO_REUSEADDR, 1)) { 
     socket_close($this->wsRead[0]); 
     return false; 
    } 
    if (!socket_bind($this->wsRead[0], $host, $port)) { 
     socket_close($this->wsRead[0]); 
     return false; 
    } 
    if (!socket_listen($this->wsRead[0], 10)) { 
     socket_close($this->wsRead[0]); 
     return false; 
    } 

    $write = array(); 
    $except = array(); 

    $nextPingCheck = time() + 1; 
    while (isset($this->wsRead[0])) { 
     $changed = $this->wsRead; 
     $result = socket_select($changed, $write, $except, 1); 

     if ($result === false) { 
      socket_close($this->wsRead[0]); 
      return false; 
     } 
     elseif ($result > 0) { 
      foreach ($changed as $clientID => $socket) { 
       if ($clientID != 0) { 
        // client socket changed 
        $buffer = ''; 
        $bytes = @socket_recv($socket, $buffer, 4096, 0); 
        //$this->log($buffer); 
        if ($bytes === false) { 
         // error on recv, remove client socket (will check to send close frame) 
         $this->wsSendClientClose($clientID, self::WS_STATUS_PROTOCOL_ERROR); 
        } 
        elseif ($bytes > 0) { 
         // process handshake or frame(s) 
         //$this->log("hi".$buffer); 
         if (!$this->wsProcessClient($clientID, $buffer, $bytes)) { 
          $this->wsSendClientClose($clientID, self::WS_STATUS_PROTOCOL_ERROR); 
         } 
        } 
        else { 
         // 0 bytes received from client, meaning the client closed the TCP connection 
         $this->wsRemoveClient($clientID); 
        } 
       } 
       else { 
        // listen socket changed 
        $client = socket_accept($this->wsRead[0]); 
        if ($client !== false) { 
         // fetch client IP as integer 
         $clientIP = ''; 
         $result = socket_getpeername($client, $clientIP); 
         //$this->log($clientIP); 
         $clientIP = ip2long($clientIP); 
         //$this->log($clientIP); 

         if ($result !== false && $this->wsClientCount < self::WS_MAX_CLIENTS && (!isset($this->wsClientIPCount[$clientIP]) || $this->wsClientIPCount[$clientIP] < self::WS_MAX_CLIENTS_PER_IP)) { 
          $this->wsAddClient($client, $clientIP); 
         } 
         else { 
          socket_close($client); 
         } 
        } 
       } 
      } 
     } 

     if (time() >= $nextPingCheck) { 
      $this->wsCheckIdleClients(); 
      $nextPingCheck = time() + 1; 
     } 
    } 

    return true; // returned when wsStopServer() is called 

我認爲這個問題圍繞着socket_select()函數,它無法選擇創建的套接字。 如何使它工作? 請大家幫忙,因爲即使經過多次嘗試,我仍無法解決此問題。

UPDATE

我發現這個問題而產生由於對亞馬遜舊版本的Python。所以我改變了Python版本2.6/2.7

此外我替換socket.io庫來運行我的聊天。它的工作非常順利。

回答

0

您正在使用的WebSocket實現似乎實現了WebSocket協議的不推薦使用的Hixie-76版本,Firefox(以及Chrome和其他)不再支持該版本。我建議看一下Ratchet。這是最新的,經過充分測試。

+0

嗨oberstet。感謝回覆。但我的項目是在本地主機以及我的開發服務器上工作。使用chrome,firefox和ie10。它只是沒有在亞馬遜ec2上工作。另外,我必須從頭開始我的代碼,我不能使用任何外部庫,我不能看到。 – addy

+0

您使用的端口是<1024。如果是這樣,您需要在根目錄下運行或爲PHP可執行文件設置適當的特定權限。在Windows上,這不是必需的,而是Unix。另一個潛在的問題是:中介。使用WSS來排除這一點。 – oberstet

+0

不,我正在使用端口9300。 – addy