The Problem
I recently posted a question trying to understand how to implement a Flask-SocketIO setup on an IIS webserver (I could only get it to work on my local development server). I was pointed in the direction of using IIS as a reverse proxy, rather than actually running the application directly on IIS.
I have since setup this structure and it's closer to working, but still not there yet. Forgive my ignorance, I'm not well versed in websockets nor webserver configuration and the like; but no amount of Googling seems to help.
Setup
- Windows Server
- IIS (Reverse Proxy) ["Websocket" Protocol has been installed and enabled]
- Flask
- Eventlet
- Flask-SocketIO
Reverse Proxy Web Config
(Some values removed for security/privacy purposes).
HTTPS Redirect rewrite rule is disabled for now, while I'm trying to figure out what's going wrong.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="HTTPS Redirect" enabled="false" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="off" />
<add input="{SERVER_PORT}" pattern="^80$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}:4440/{R:1}" appendQueryString="false" />
</rule>
<rule name="ReverseProxyInboundRule1" enabled="true" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://127.0.0.1:4441/{R:1}" />
<serverVariables>
<set name="HTTP_X_FORWARDED_PORT" value="4440" />
<set name="HTTP_X_FORWARDED_HOST" value="subdomain.domain.co.uk" />
<set name="HTTP_X_FORWARDED_PROTO" value="https" />
</serverVariables>
<conditions>
</conditions>
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1" enabled="true">
<match filterByTags="A, Form, Img" pattern="(.*)://127.0.0.1:4441/(.*)" />
<action type="Rewrite" value="{C:1}://subdomain.domain.co.uk:4440/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<webSocket enabled="true" />
</system.webServer>
<location path="" overrideMode="Deny">
</location>
</configuration>
Flask-SocketIO (Server-Side)
# Bottom of __init__.py
from werkzeug.middleware.proxy_fix import ProxyFix
from flask_socketio import SocketIO
socketio.init_app(app, logger=True, engineio_logger=True, cors_allowed_origins="https://subdomain.domain.co.uk:4440")
if not app.debug:
app.wsgi_app = ProxyFix(app.wsgi_app, x_port=1, x_proto=1, x_host=1)
return app
# Bottom of app entry point file
from application import create_app, socketio
app = create_app()
if __name__ == "__main__":
socketio.run(app, host="127.0.0.1", port=4441)
Flask-SocketIO (Client-Side)
// NOTE: Socket.IO JS file has been properly included in the HTML template file
$(document).ready(function() {
// Initialise SocketIO
var socket = io('/<NAMESPACE>');
// Join room
socket.on('connect', function() {
socket.emit('joined', {room: <ROOM_NAME>});
});
// Continued... (this is all that's really relevant for these purposes)
});
It all works fine on my development server, and I turned Flask-SocketIO logging on to try to get a better understanding of the situation. I noticed that after the Received request to upgrade to websocket
message, there's another message that confirms the websocket connection was successful (I can't remember exactly what the message says, but it's to that effect). When I do the same via the IIS reverse proxy, I do not see that second message. Additionally, every so often, I get the following error message:
BrokenPipeError: [WinError 10058] A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous shutdown call
Additionally, the browser (after attempting to upgrade to the websocket protocol) then sends thousands of GET
requests in quick succession (presumably reverting to long-polling). This is seemingly never-ending.
If anyone has any suggestions as to how I might resolve this, I'd be greatly appreciative. I've been at this for about a week now and I'm just going round in circles at this point...
Thanks