2015-10-22 20 views
12

Ho setacciato Internet cercando di trovare qualcuno che potrebbe riscontrare questo problema ma venire a mani vuote. Quindi ecco:Websockets su Tomcat 8 + IIS 8 con ARR 3 non funzionano

Abbiamo un'applicazione web java (basata su Spring MVC 4). Si trova dietro Microsoft IIS che funge da bilanciamento del carico/proxy inverso usando ARR (Application Request Routing) v3.

Questa IIS sta eseguendo il bilanciamento del carico con ARR per 3 diversi ambienti (tutti in esecuzione il codice Java stesso): dev.example.com, demo.example.com e qa.example.com.

L'applicazione serve notifiche ai browser degli utenti che utilizzano WebSockets via SockJS e stompjs e questo ha tutto lavorato bene, mentre i server di applicazioni erano su Tomcat 7. Dopo l'aggiornamento l'ambiente qa.example.com a Tomcat 8, i collegamenti websocket smesso di funzionare - è ricade sulle richieste XHR POST.

Desidero sottolineare che non sono state apportate modifiche a IIS, ma solo al server delle applicazioni qa.

Ecco un esempio di richiesta/risposta dall'ambiente dev (di lavoro):

Accept-Encoding: gzip, deflate, sdch 
Accept-Language: en-US,en;q=0.8 
Cache-Control: no-cache 
Connection: Upgrade 
Cookie: <cookies snipped> 
Host: dev.example.com 
Origin: https://dev.example.com 
Pragma: no-cache 
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits 
Sec-WebSocket-Key: E7aIek0X6qcO9PAl1n6w4Q== 
Sec-WebSocket-Version: 13 
Upgrade: websocket 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36 

risposta

Cache-Control: no-cache, no-store, max-age=0, must-revalidate 
Connection: Upgrade 
Date: Thu, 22 Oct 2015 02:19:35 GMT 
Expires: 0 
Pragma: no-cache 
Sec-WebSocket-Accept: dKYK05s4eP87iA20aSo/3ntOrPU= 
Server: Microsoft-IIS/8.0 
Strict-Transport-Security: max-age=31536000 ; includeSubDomains 
Upgrade: Websocket 
X-Content-Type-Options: nosniff 
X-Frame-Options: DENY 
X-Powered-By: ARR/3.0 
X-XSS-Protection: 1; mode=block 

Qui è un esempio di richiesta/risposta dall'ambiente qa (rotto):

Accept-Encoding: gzip, deflate, sdch 
Accept-Language: en-US,en;q=0.8 
Cache-Control: no-cache 
Connection: Upgrade 
Cookie: <cookies snipped> 
Host: qa.example.com 
Origin: https://qa.example.com 
Pragma: no-cache 
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits 
Sec-WebSocket-Key: jTOIAT0+o35+Qi0ZWh2gyQ== 
Sec-WebSocket-Version: 13 
Upgrade: websocket 
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.71 Safari/537.36 

Risposta:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate 
Connection: Upgrade 
Date: Thu, 22 Oct 2015 02:18:30 GMT 
Expires: 0 
Pragma: no-cache 
Sec-WebSocket-Accept: P+fEH8pvxcu3sEoO5fDizjSbwJc= 
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15 
Server: Microsoft-IIS/8.0 
Strict-Transport-Security: max-age=31536000 ; includeSubDomains 
Upgrade: Websocket 
X-Content-Type-Options: nosniff 
X-Frame-Options: DENY 
X-Powered-By: ARR/3.0 
X-XSS-Protection: 1; mode=block 

L'unica differenza evidente è che la risposta qa comprende un'intestazione Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15 mentre la risposta dev non.

Ho attivato "Failed Request Tracing" su IIS per eseguire il debug della risposta 101 e posso vedere che ci sono alcune intestazioni che vengono sovrascritte da IIS, ovvero l'intestazione Sec-WebSocket-Accept.

IIS mostra anche che quella richiesta sta creando un errore 502.5. Ho trovato questo e ho trovato questo: https://support.microsoft.com/en-us/kb/943891 che dice che 502.5 è "WebSocket failure (ARR)" e questo è tutto ciò che dice. Stranamente, però, Chrome Dev Tools mostra che risponde con un 101 proprio come dovrebbe ...

Ho provato questo tutto con un server delle applicazioni locale (Tomcat 8 senza IIS) e le websocket funzionavano bene. Tomcat 7 + IIS + ARR + WebSockets funziona perfettamente. Tomcat 8 + IIS + ARR + WebSockets non lo fa.

La mia versione esatta di Tomcat 8 è 8.0.28 - ma ho ottenuto gli stessi risultati su Tomcat 8.0.26.

Il mio prossimo passo è continuare a eseguire il downgrade di Tomcat 8 attraverso versioni secondarie e vedere se qualcosa cambia. Aggiornerò qui se scopro qualcosa.

Aggiornamento

Ecco una risposta dal mio server locale (no IIS):

Cache-Control: no-cache, no-store, max-age=0, must-revalidate 
Connection: upgrade 
Date: Thu, 22 Oct 2015 13:59:23 GMT 
Expires: 0 
Pragma: no-cache 
Sec-WebSocket-Accept: 718HnPxHN8crYYzNGFjQf7w8O+Y= 
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15 
Server: Apache-Coyote/1.1 
Strict-Transport-Security: max-age=31536000 ; includeSubDomains 
Upgrade: websocket 
X-Content-Type-Options: nosniff 
X-Frame-Options: DENY 
X-XSS-Protection: 1; mode=block 

Sembra un po 'come il rotto qa richiesta, ma funziona benissimo. Quindi immagino che la cosa Sec-WebSocket-Extensions fosse un'aringa rossa. Anche Upgrade: websocket e Connection: upgrade è in minuscolo sul server locale, mentre è Websocket e Upgrade quando si inserisce IIS in primo piano.

Sec-WebSocket-Extensions ha anche uno spazio finale in qa dopo il permessage-deflate; ma il locale no.

Update 2

Tutto funziona bene sul qa ambiente in Microsoft Edge (Windows 10) Non ho ancora provato Internet Explorer 11, ma devo supporre che probabilmente funziona anche. Firefox e Chrome su OSX non funzionano.

Update 3

Richiesta da Tomcat prima che venga modificato da IIS/ARR:

HTTP/1.1 101 Switching Protocols 
Server: Apache-Coyote/1.1 
Upgrade: websocket 
Connection: upgrade 
Sec-WebSocket-Accept: luP49lroNK9qTdaNNnSCLXnxAWc= 
Sec-WebSocket-Extensions: permessage-deflate;client_max_window_bits=15 
Date: Tue, 27 Oct 2015 21:10:48 GMT 
+0

Sei in grado di disabilitare la compressione su websockets per Tomcat? Sec-WebSocket-Extensions: permessage-deflate; suggerisce che si sta comprimendo, nella mia esperienza IIS non ha proxy websocket compressi. –

+0

@ timmah.faase Farò un tentativo e riferirò –

+0

Quindi, ho tentato di aggiungere questa opzione alla mia configurazione di Tomcat: '-Dorg.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS = true' che doveva fare il trucco secondo ai documenti: 'Se è vero, disabilita tutte le estensioni predefinite fornite dal server, come la compressione dei messaggi. ma non sembra che abbia modificato le intestazioni di risposta per tutte le –

risposta

2

ho scoperto la soluzione, anche se non è soddisfacente come vorrei che fosse.

Nel nostro progetto di pom.xml avevamo spring-core:4.2.5 ma spring-websocket e spring-messaging erano 4.1.6. La mancata corrispondenza della versione stava causando alcuni problemi chiaramente.

L'impostazione -Dorg.apache.tomcat.websocket.DISABLE_BUILTIN_EXTENSIONS=true nelle opzioni di avvio di Tomcat quando le versioni erano non corrispondenti non ha avuto alcun effetto. Impostando l'opzione JVM quando le versioni erano lo stesso funzionava come previsto.

La risposta 101 ora non contiene permessage-deflate e websockets sono in grado di connettersi senza problemi tramite IIS. La nostra applicazione non invia molti dati attraverso le prese quindi siamo stati OK a fare questo compromesso.

+1

Tutte le librerie di primavera che sto usando sono 4.3.6 e anch'io sto vivendo questo problema. Posso confermare che la disattivazione delle estensioni websocket funziona, ma devo ammettere che non si tratta di una soluzione molto soddisfacente in quanto la compressione va alla porta. Qualsiasi altra soluzione sarebbe molto gradita. – Ron

2

Lo stesso problema su Tomcat7 e IIS8 utilizzando ARR3. Non stiamo usando le librerie Spring.

Nessun frame viene inviato dopo aver stabilito la connessione Web se le estensioni websocket sono abilitate. Ma se disabilitiamo le estensioni websocket, tutto funziona perfettamente.

+0

Mi chiedo come possiamo creare una segnalazione di bug per questo - sembra di sicuro un bug! C'è un Microsoft Connect per IIS mi chiedo ... –