socket.io 无法通过 express 与后端通信
socket.io cannot communicate with back-end through express
我正在使用 socket.io 从 Express 应用程序中获取一些数据。在 localhost:8080 上一切正常,但是当我将代码部署到服务器时,客户端 socket.io 无法通过快速服务器与后端 socket.io 通信。我在服务器上有一个 apache,它将所有内容转发到 localhost:8080,包括域。com/socket.io/?transform=polling... 并将请求扩展到快速服务器,但表示 returns 一个 404(它来自 express,而不是来自 apache)。我没有想法,可能是什么问题?这是我的代码:
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
甚至我也有同样的问题。服务器正在侦听的端口是在服务器上打开的端口。由于在本地所有端口都是打开的,但在服务器上,情况并非如此。
既然你特别说它在本地工作,而且我在你的代码中没有看到任何特别之处,我真的认为问题出在你的 Apache 配置上。
您需要拥有并启用一个名为 mod_proxy_wstunnel
的模块,才能让您的 WebSocket 流量正常工作并正确代理到您的快速应用程序。要么你有 Apache 2.4,要么你需要应用 this patch found in this blogpost and compile again. There is also another blog 逐步详细说明你应该在 Ubuntu.
下做什么
确保您拥有模块并加载它之后,您必须调整您的配置以使用 ProxyPass
指令添加一些 WebSocket 代理
ProxyRequests Off
ProxyPass "/socket-io/" "ws://localhost:8080/socket.io/"
ProxyPassReverse "/socket-io/" "ws://localhost:8080/socket.io/"
您可能还想尝试对随 WebSockets 发送的升级 header 使用重写条件:
RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteRule /(.*) ws://localhost:8000/ [P,L]
ProxyPass / http://localhost:8000/
已在 this comment 或此特定线程中看到一般情况,其中公开了一些您可以尝试的其他可能的解决方案。
你应该采取的调试步骤是在你的 express 应用程序中有一个模拟客户端 运行 并尝试使用本地主机或任何环回 IP 地址连接到服务器端口。换句话说(纯粹作为一个临时测试工具)你将一个 socket.io Node 客户端放入你的 Express 应用程序中,它被实例化并立即尝试连接到 Socket.io 服务器(它也在 Express 应用程序中) .这应该工作。
如果确实有效,则表明您的 express 服务器没有问题。然后,在您刚刚添加到您的快捷应用程序的客户端上,您应该将连接地址从本地 IP 更改为服务器的实际 IP 地址。
如果不起作用,您的问题可能是服务器端。
我的猜测是您的 apache 服务器正在正确转发轮询请求,但是当 Socket.io 尝试切换到 websockets 时,Apache 拒绝 WS 请求并且 socket.io 正在处理此拒绝在内部——这就是为什么 404 似乎来自 express。
我正在使用 socket.io 从 Express 应用程序中获取一些数据。在 localhost:8080 上一切正常,但是当我将代码部署到服务器时,客户端 socket.io 无法通过快速服务器与后端 socket.io 通信。我在服务器上有一个 apache,它将所有内容转发到 localhost:8080,包括域。com/socket.io/?transform=polling... 并将请求扩展到快速服务器,但表示 returns 一个 404(它来自 express,而不是来自 apache)。我没有想法,可能是什么问题?这是我的代码:
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
甚至我也有同样的问题。服务器正在侦听的端口是在服务器上打开的端口。由于在本地所有端口都是打开的,但在服务器上,情况并非如此。
既然你特别说它在本地工作,而且我在你的代码中没有看到任何特别之处,我真的认为问题出在你的 Apache 配置上。
您需要拥有并启用一个名为 mod_proxy_wstunnel
的模块,才能让您的 WebSocket 流量正常工作并正确代理到您的快速应用程序。要么你有 Apache 2.4,要么你需要应用 this patch found in this blogpost and compile again. There is also another blog 逐步详细说明你应该在 Ubuntu.
确保您拥有模块并加载它之后,您必须调整您的配置以使用 ProxyPass
指令添加一些 WebSocket 代理
ProxyRequests Off
ProxyPass "/socket-io/" "ws://localhost:8080/socket.io/"
ProxyPassReverse "/socket-io/" "ws://localhost:8080/socket.io/"
您可能还想尝试对随 WebSockets 发送的升级 header 使用重写条件:
RewriteEngine On
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteRule /(.*) ws://localhost:8000/ [P,L]
ProxyPass / http://localhost:8000/
已在 this comment 或此特定线程中看到一般情况,其中公开了一些您可以尝试的其他可能的解决方案。
你应该采取的调试步骤是在你的 express 应用程序中有一个模拟客户端 运行 并尝试使用本地主机或任何环回 IP 地址连接到服务器端口。换句话说(纯粹作为一个临时测试工具)你将一个 socket.io Node 客户端放入你的 Express 应用程序中,它被实例化并立即尝试连接到 Socket.io 服务器(它也在 Express 应用程序中) .这应该工作。
如果确实有效,则表明您的 express 服务器没有问题。然后,在您刚刚添加到您的快捷应用程序的客户端上,您应该将连接地址从本地 IP 更改为服务器的实际 IP 地址。
如果不起作用,您的问题可能是服务器端。
我的猜测是您的 apache 服务器正在正确转发轮询请求,但是当 Socket.io 尝试切换到 websockets 时,Apache 拒绝 WS 请求并且 socket.io 正在处理此拒绝在内部——这就是为什么 404 似乎来自 express。