Nginx not passing websocket upgrade response back

2019-04-10 16:58发布

问题:

I am using Nginx + Websockets on a precise 64 vagrant box, with c#/mono for the app server. The goal is to serve up static content directly through Nginx, and handle both plain 'ol http service requests (on /service) and also websocket requests (on /webSocket) all on the same port. Here's the relevant conf:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

server {
    listen              80  default_server;

    # (1)
    location / {
        root            /var/www;
        index           index.html;
    }

    # (2)
    location /service {
        add_header      Access-Control-Allow-Origin *;
        proxy_pass      http://localhost:9000;
    }

    # (3)
    location /webSocket {
        proxy_pass         http://localhost:9000;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection $connection_upgrade;
    }
}

Most of it is working well. Static content, yes, service requests, yes, and even the first part of websockets. I am getting a well-formed 101 Switching Protocols request from my client (Firefox or Chrome). I am making a nice http upgrade response and sending it. And then the client does... nothing... nothing is received.

But the crazy thing is, when I give up and manually kill my server side app, and the client web socket closes with error, THEN the Response Headers show up on the client browser debugger. The whole thing looks like:

REQUEST HEADERS
Request URL:    http://localhost:8086/webSocket
Request Method:     GET
Status Code:    HTTP/1.1 101 Switching Protocols
Request Headers 16:18:50.000
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0)    Gecko/20100101  Firefox/38.0
Upgrade:    websocket
Sec-WebSocket-Version:  13
Sec-WebSocket-Key:  Nx0sUAemOFWM2rsaCAJpfQ==
Sec-WebSocket-Extensions:   permessage-deflate
Pragma: no-cache
Origin: http://localhost:8086
Host:   localhost:8086
Connection: keep-alive, Upgrade
Cache-Control:  no-cache
Accept-Language:    en-US,en;q=0.5
Accept-Encoding:    gzip, deflate
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

RESPONSE HEADERS Δ19660ms
Upgrade:    websocket
Transfer-Encoding:  chunked
Server: nginx/1.1.19
Sec-WebSocket-Accept:   gNiAeqxcVjkiReIpdtP0EZiClpg=
Date:   Mon, 08 Jun 2015 20:18:48 GMT
Connection: keep-alive

NO RESPONSE BODY Δ0ms

There's no evidence that my server app is not flushing out its send data right away - I'm using async TcpSocket.BeginSend and FinishSend and the send seems to complete right away. And it works fine on plain http service comm.

So where is my websocket message data going??? It seems like Nginx doesn't want to send it back to my client, except until I close the Tcp connection from the server side.

Has anybody experienced something like this before. Everything I've read on Nginx and Websockets is concerned with the basic setup that gets the hop-by-hop upgrade working, and I've got that. No one has anything to say as to why sending back from the server side doesn't seem to go anywhere.