Websockets. FastCGI or WSGI. SSL. Same domain. How

2019-05-22 22:29发布

问题:

Question

I've built an app in two parts: a low-overhead server which listens for long-polling and websocket connections using Socket.IO and a regular WSGI-compatible Python webapp. The former would be bound to the path /socket.io/ and the latter to every other path. Additionally, files in /static/ can be served directly from the filesystem and with far-future expiration headers.

I figured it would easy to put a proxy in front of the two services which would serve the whole site via SSL, but I can't find a good solution. Can you help?

Background

I split the app into two parts because it made sense — much more memory is required to process a regular web request (database queries, middleware) than open websocket sockets. I still think this was a good idea but it could have been a mistake.

The Python webapp is is WSGI-compliant but should probably be served using FastCGI; I think the FastCGI processes should have long-running Python interpreters, not the proxy. Again, I could be wrong here.

I know lighttpd has a mod_websocket, and I've built and installed both, but I can't seem to configure it correctly. I think it's a layering problem — mod_websocket simply shuttles bytes to and from a backend TCP service, but maybe that's okay...

Updates

Let me know if any additional information would help, like my lighttpd config, and I'll post it here.

回答1:

Figured it out. Here's my lighttpd config, abbreviated:

# The port of the Socket.IO daemon
var.daemon_port = 9000

ssl.engine = "enable"
ssl.pemfile = "/path/to.pem"

$HTTP["url"] =~ "^/socket.io" {
  proxy.server = ( "" =>
    (("host" => "127.0.0.1", "port" => daemon_port))
  )
}

alias.url = (
  "/favicon.ico" => "/path/to/static/favicon.ico",
  "/robots.txt" => "/path/to/static/robots.txt",
)

fastcgi.server = ( "/app.fcgi" => # Arbitrary path name
  ((
    "bin-path" => "/path/to/app.fcgi",
    "socket" => "/tmp/app-fcgi-" + PID + ".sock",
    "check-local" => "disable",
    "fix-root-scriptname" => "enable",
    "max-procs" => 1,
  ))
)

url.rewrite-once = (
  "^(/socket.io/.*)$" => "$1",
  "^(/(favicon.ico|robots.txt))$" => "$1",
  "^(/.*)$" => "/app.fcgi$1",
)