2017-05-29 74 views
0

我正在使用socket.io從快速應用中獲取一些數據。在localhost:8080上一切正常,但是當我將代碼部署到服務器時,客戶端socket.io無法通過express服務器與後端socket.io進行通信。我有一個服務器上的Apache,將所有內容轉發到localhost:8080,其中包括domain.com/socket.io/?transform=polling ...並將請求擴展到express服務器,但是express將返回404(它來自表達,而不是從apache)。我沒有想法,可能是什麼問題?這裏是我的代碼:socket.io無法通過快遞與後端進行通信

express = require "express" 
jade = require "jade" 
fs = require "fs" 

class Bootstrap 
_self = undefined 
routes: 
    DEFAULT_PATH: "/" 
    TEMPLATE_PATH: "/load/:view" 
    DIRECTIVE_PATH: "/directive/:template" 
options: 
    templatePath: "#{__dirname}/../src/templates" 
    isDev: "#{__dirname}/../dev" 
contentPath: "#{__dirname}/../frontend" 
libraryPath: "#{__dirname}/../bower_components" 
port: 8080 
status: 
    notFound: 404 
isDev: undefined 

constructor: -> 
    _self = @ 
    @isDev = fs.existsSync @options.isDev 
    @app = express() 

    @app.use "/frontend", express.static(@options.contentPath) 
    @app.use "/bower_components", express.static(@options.libraryPath) 
    @app.set "views", @options.templatePath 
    @app.set "view engine", "jade" 
    @app.engine "jade", jade.__express 

    @app.get @routes.DEFAULT_PATH, (request, response)-> 
    appData = 
     data: 
     isDev: _self.isDev 
    response.render "index", appData 
    @app.get @routes.TEMPLATE_PATH, (request, response)-> 
    view = request.param "view" 
    response.render view 
    @app.get @routes.DIRECTIVE_PATH, (request, response)-> 
    template = request.param("template").replace ".html", "" 
    response.render "directives/"+template 
    @app.use (request, response, next)-> 
    _self.logger.warning "404 Not Found!: " + request.originalUrl 
    response.status(_self.options.status.notFound) 
     appData = 
     data: 
      isDev : _self.isDev 
      request: request 
     response.render "404", appData 

    @server = @app.listen @options.port 
    @io = require("socket.io").listen @server 

    @logger = require("./logger.js") 
    @logger.init @isDev 

    @socketConnector = require("./live.js") 
    @socketConnector.init @io 

    @ 

new Bootstrap() 

您可以在這裏找到整個代碼:https://github.com/eyurdakul/ejder.be

+0

你能提供apache重寫規則和日誌嗎?你還可以記錄來自該服務器的傳入請求嗎?這將有助於調試問題。 – TheGiantBeast

回答

1

既然你明確說過它在本地工作,我沒有看到任何特殊的代碼,我真的認爲這個問題駐留在你的Apache配置。

有一個名爲mod_proxy_wstunnel的模塊,您需要啓用該模塊才能讓WebSocket流量正常工作並正確代理您的快速應用。要麼你有Apache 2.4,或者你需要申請this blogpost中的this patch並重新編譯。還有另一個blog詳細說明你應該在Ubuntu下做什麼。

確保您有模塊及其加載後,你必須調整你的配置使用ProxyPass指令

ProxyRequests Off 
ProxyPass  "/socket-io/" "ws://localhost:8080/socket.io/" 
ProxyPassReverse "/socket-io/" "ws://localhost:8080/socket.io/" 

您也可能想嘗試使用一個重寫條件添加一些的WebSocket代理對正在使用WebSockets發送的升級頭:

RewriteEngine On 
RewriteCond %{HTTP:Connection} Upgrade [NC] 
RewriteRule /(.*) ws://localhost:8000/$1 [P,L] 
ProxyPass/http://localhost:8000/ 

已經看到了this comment或一般這個特定的線程,這暴露出一些其他可能的解決方案,你可以試試。

+0

mod_proxy_wstunnel是解決方案。 – eyurdakul

-1

即使我有同樣的問題。服務器正在偵聽的端口是在服務器上打開的端口。就本地而言,所有的端口都是開放的,但在服務器上,情況並非如此。

+0

那麼,我認爲他們都使用端口8080,因爲我沒有使用專用端口的插座。顯然,這是socket.io如何與express一起使用。 – eyurdakul

0

你應該採取的一個調試步驟是在快速應用程序中運行模擬客戶端,並嘗試使用本地主機或任​​何回送IP地址連接到服務器端口。換句話說(純粹作爲一個臨時測試工具),您將一個socket.io Node客戶端放入您的Express應用程序中,該應用程序被實例化並立即嘗試連接到Socket.io服務器(它也在快速應用程序中)。這應該工作。

如果確實有效,您已經確定您的快遞服務器不是問題。然後,在剛剛添加到快速應用程序的客戶端上,應該將連接地址從本地IP更改爲服務器的實際IP地址。

如果它不起作用,您的問題可能是服務器端。

我的猜測是你的Apache服務器正在轉發輪詢請求,但是當Socket.io嘗試切換到websockets時,Apache正在拒絕WS請求,而socket.io正在內部處理這種拒絕 - 這是爲什麼404似乎來自快遞。

相關問題