通过 Apache/Varnish 的 Websocket 失败了
Websocket via Apache/Varnish failed
几天来我一直在尝试让这个与 websocket 的连接工作,但是在尝试通过 Javascript 连接到它时,我仍然最终收到错误。
javascript抛出的错误如下:
WebSocket connection to 'ws://lmc-staging.mydomain.org:8081/' failed: Connection closed before receiving a handshake response
brainsocket.min.js:1 Event {clipboardData: undefined, path: NodeList[0], cancelBubble: false, returnValue: true, srcElement: WebSocket…}bubbles: false cancelBubble: false cancelable: false clipboardData: undefined currentTarget: WebSocket defaultPrevented: false eventPhase: 0path: NodeList[0] returnValue: true srcElement: WebSockettarget: WebSockettimeStamp: 1421938720697 type: "error"__proto__: Event
brainsocket.min.js:1 WebSocket is already in CLOSING or CLOSED state.
该请求是使用 Varnish piped
到 Apache Web 服务器 (xxx.xxx.xxx.203)。清漆配置发布如下:
# This is a basic VCL configuration file for varnish. See the vcl(7)
# man page for details on VCL syntax and semantics.
#
# Default backend definition. Set this to point to your content
# server.
#
# Internal hosts; same as purge, but separated for clarity.
acl internal {
"localhost";
"127.0.0.1";
"xxx.xxx.xxx.0"/24;
"xxx.xxx.xxx.203";
"xxx.xxx.xxx.204";
}
# Hosts allowed to purge cache
acl purge {
"localhost";
"127.0.0.1";
"xxx.xxx.xxx.0"/24;
"xxx.xxx.xxx.203";
"xxx.xxx.xxx.204";
}
# DEV webserver
backend vsrv1474 {
.host = "xxx.xxx.xxx.203";
.port = "80";
.connect_timeout = 300s;
.first_byte_timeout = 300s;
.between_bytes_timeout = 300s;
}
# DEV brainsocket
backend brainsocket {
.host = "xxx.xxx.xxx.203";
.port = "8081";
.connect_timeout = 300s;
.first_byte_timeout = 300s;
.between_bytes_timeout = 300s;
}
# PROD webserver
backend vsrv1475 {
.host = "xxx.xxx.xxx.204";
.port = "80";
#.connect_timeout = 5s;
#.first_byte_timeout = 60s;a
#.between_bytes_timeout = 60s;
.connect_timeout = 300s;
.first_byte_timeout = 300s;
.between_bytes_timeout = 300s;
}
sub vcl_recv {
# Allow purge from hosts in purge acl or return 405
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed";
}
return(lookup);
}
# entry for brainsocket
if (req.http.Upgrade ~ "(?i)websocket") {
set req.backend = brainsocket;
return (pipe);
}
# end entry for brainsocket
if (req.url ~ "/dev/" || req.http.host == "staging.mydomain.org" || req.http.host == "dev.mydomain2.org" || req.http.host == "lmc-staging.mydomain.org" ){
set req.backend = vsrv1474;
return(pass);
} elsif ( req.http.host == "www.mydomain2.org" || req.http.host == "lmc.mydomain2.org" ) {
set req.backend = vsrv1475;
} else {
set req.backend = vsrv1475;
}
if (req.url ~ "^/misc/progress'.js'?[0-9]+$") {
set req.url = "/misc/progress.js";
}
if (req.url ~ "^/admin/content/backup_migrate/export") {
return (pipe);
}
# Do not cache these paths.
if(req.url ~ "^/status'.php$"||
req.url ~ "^/update'.php$"||
req.url ~ "^/install'.php" ||
req.url ~ "^/admin" ||
req.url ~ "^/admin/.*$"||
req.url ~ "^/user" ||
req.url ~ "^/user/.*$" ||
req.url ~ "^/users/.*$" ||
req.url ~ "^/info/.*$" ||
req.url ~ "^/flag/.*$"||
req.url ~ "^.*/ajax/.*$"||
req.url ~ "^.*/facebook-rss.xml$" ||
req.url ~ "^.*/twitter-rss.xml$" ||
req.url ~ "^.*/ahah/.*$") {
return(pass);
}
# Disallow outside access to cron.php or install.php
if (req.url ~ "^/(cron|install)'.php$" && !client.ip ~ internal) {
error 404 "Page not found.";
}
# Always cache the following file types for all users.
if (req.url ~ "(?i)'.(png|gif|jpeg|jpg|ico|swf|css|js|html|htm|woff)('?[a-z0-9]+)?$") {
unset req.http.Cookie;
}
# Remove all cookies that Drupal doesn't need to know about. ANY remaining
# cookie will cause the request to pass-through to Apache. For the most part
# we always set the NO_CACHE cookie after any POST request, disabling the
# Varnish cache temporarily. The session cookie allows all authenticated users
# to pass through as long as they're logged in.
if (req.http.Cookie) {
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
set req.http.Cookie = regsuball(req.http.Cookie, ";(S{1,2}ESS[a-z0-9]+|NO_CACHE|CI_SESSION|ci_session|token|PHPSESSID)=", "; '1=");
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
if (req.http.Cookie == "") {
# If there are no remaining cookies, remove the cookie header. If there
# aren't any cookie headers, Varnish's default behavior will be to cache
# the page.
unset req.http.Cookie;
}
else {
# If there is any cookies left (a session or NO_CACHE cookie), do not
# cache the page. Pass it on to Apache directly.
return (pass);
}
}
# Remove the "has_js" cookie
set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
# Remove the "Drupal.toolbar.collapsed" cookie
set req.http.Cookie = regsuball(req.http.Cookie, "Drupal.toolbar.collapsed=[^;]+(; )?", "");
# Remove any Google Analytics based cookies
set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
# Remove the Quant Capital cookies (added by some plugin, all __qca)
set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");
# Are there cookies left with only spaces or that are empty?
if (req.http.cookie ~ "^ *$") {
unset req.http.cookie;
}
# Cache static content unique to the theme (so no user uploaded images)
if (req.url ~ "^/themes/" && req.url ~ ".(css|js|png|gif|jp(e)?g)") {
unset req.http.cookie;
}
}
sub vcl_pipe {
#copy the upgrade header
if (req.http.upgrade) {
set bereq.http.upgrade = req.http.upgrade;
}
#closing the connection might be necessary for some applications as the connection will remain open forever and consume resources if not properly stopped by server or client
#set bereq.http.Connection = "close";
}
sub vcl_miss {
if (req.request == "PURGE") {
purge;
error 200 "Purged";
}
}
sub vcl_hit {
if (req.request == "PURGE") {
purge;
error 200 "Purged";
}
}
sub vcl_fetch {
unset beresp.http.Vary;
set beresp.http.x-url = req.url;
set beresp.http.x-host = req.http.host;
# Don't allow static files to set cookies.
if (req.url ~ "(?i)'.(png|gif|jpeg|jpg|ico|swf|css|js|html|htm)('?[a-z0-9]+)?$") {
# beresp == Back-end response from the web server.
unset beresp.http.set-cookie;
}
# Check if no ttl and a cookie set.
if (beresp.ttl <= 0s && beresp.http.Cookie ~ ".+" ) {
set beresp.http.X-Cacheable = "NO:Not Cacheable: No ttl; has cookie";
# Varnish determined the object was not cacheable
} elsif (beresp.ttl <= 0s) {
set beresp.http.X-Cacheable = "NO:Not Cacheable: No ttl; no cookie";
# You don't wish to cache content for logged in users
} elsif (req.http.Cookie ~ "(S{1,2}ESS[a-z0-9]+|NO_CACHE|CI_SESSION|ci_session|token|PHPSESSID)") {
set beresp.http.X-Cacheable = "NO:Got Session";
return(hit_for_pass);
# You are respecting the Cache-Control=private header from the backend
} elsif (beresp.http.Cache-Control ~ "private") {
set beresp.http.X-Cacheable = "NO:Cache-Control=private";
return(hit_for_pass);
# Varnish determined the object was cacheable
} else {
set beresp.http.X-Cacheable = "YES";
}
return(deliver);
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
unset resp.http.x-url; # Optional
unset resp.http.x-host; # Optional
unset resp.http.Server;
unset resp.http.X-Generator;
unset resp.http.X-Powered-By;
unset resp.http.X-Drupal-Cache;
}
我正在使用brainsocket包,它允许您使用Laravel创建客户端和服务器端套接字。Brainsocket使用Ratchet作为其底层websocket层。
问题(正如 Marcel Dumont 所建议的那样)与 Varnish 未配置为侦听端口 8081 的事实有关。因此,我们将前端客户端重定向到端口 80 上的连接,并依靠 Varnish 将信息通过管道传输到端口 8081 上的底层 websocket。
相关文章:
- chrome在WebSocket握手期间获取新错误
- 当json解析空响应时,Whatwg-Fetch失败,我该如何防止它
- ReactJS和SpringDataRest缓存问题可能与websocket有关
- JsFiddle在分叉后描述失败
- Node.js上的WebSocket,并在所有连接的客户端之间共享消息
- Tomcat websocket is not working
- 通过 Apache/Varnish 的 Websocket 失败了
- Websocket 握手失败 404(golang 服务器)
- WebSocket 握手失败
- 连接到测试 websocket 服务器有效,但连接到我的 Node.js 服务器失败
- 对节点应用程序进行群集时Socket.io websocket授权失败
- 如何捕获`WebSocket连接到'ws://xxx:nn'失败:连接在收到握手响应之前关闭`error
- openshift/nodeJS中的Websocket失败
- 在wss上的WebSocket连接失败
- SignalR在Chrome上使用WebSocket连接到服务器失败
- Chrome连接websocket服务器失败(操作码-1)“握手被取消”
- 我可以捕获失败的 websocket 连接的“无法建立连接”错误吗?
- 与
的 WebSocket 连接失败:WebSocket 握手期间出错:意外响应代码:404 - WebSocket连接失败:WebSocket打开握手被取消
- 当webSocket客户端连接时,节点httpServer关闭失败