Javascript 通过Apache/Varnish访问Websocket失败
几天来,我一直在尝试让这个到websocket的连接正常工作,但当我试图通过Javascript连接到它时,仍然出现了一个错误 javascript抛出的错误如下:Javascript 通过Apache/Varnish访问Websocket失败,javascript,apache,websocket,varnish,ratchet,Javascript,Apache,Websocket,Varnish,Ratchet,几天来,我一直在尝试让这个到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
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将请求传输到Apache Web服务器xxx.xxx.xxx.203。varnish配置发布在下面:
# 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 varnish正在监听端口8081吗?你的大脑插座是,但不清楚是否也配置了清漆。有没有一个简单的方法来测试这个?我查看了wireshark流量,似乎流量正在从varnish服务器中继到另一个IP,但随后它中断了。我将使用Wireshark.check out/etc/default/varnish中的屏幕截图更新我的问题,其中定义了哪个端口。或者运行netstat-an | grep8081 | grep-i在varnish机器上侦听默认情况下所有传入的头文件?我以前遇到过web套接字和代理风格的请求转发问题,在到达后端时,关键的特定于websocket的头丢失了。见: