Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I run the python websocket server of the websokets module on the localhost:5005 . The code from documentation page :

#!/usr/bin/env python
import asyncio
import websockets
import logging
logger = logging.getLogger('websockets')
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())
async def echo(websocket):
    async for message in websocket:
        print(message)
        await websocket.send(message)
async def main():
    async with websockets.serve(echo, "localhost", 5005):
        await asyncio.Future()  # run forever
asyncio.run(main())

Clients can access it by connecting to the URL ws://localhost:5005. A sample client code is given in the websockets module documentation page.
The goal is to enable clients to access the server via IIS (Windows native webserver) acting as a reverse proxy, i.e., via the URL ws://localhost/app.

IIS-10 settings:

  • Application Request Routing Cache --> Server Proxy Setting --> Enable proxy
  • Sites --> Default Web Site: I added an application named app
  • URL Rewrite: I added the following rule:
  • <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <system.webServer>
            <rewrite>
                <rules>
                    <rule name="ReverseProxy" stopProcessing="true">
                        <match url="(.*)" />
                        <action type="Rewrite" url="http://localhost:5005" logRewrittenUrl="true" />
                    </rule>
                </rules>
            </rewrite>
        </system.webServer>
    </configuration>
    

    As soon as a client attempts to connect, it gets disconnected and the server throws this exception:

    = connection is CONNECTING
    < GET / HTTP/1.1
    < Cache-Control: no-cache
    < Connection: Upgrade
    < Pragma: no-cache
    < Upgrade: websocket
    < Accept-Encoding: gzip, deflate, br, peerdist
    < Accept-Language: en-US,en;q=0.9
    < Host: localhost:5005
    < Max-Forwards: 10
    < User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
    < Origin: null
    < Sec-WebSocket-Version: 13
    < Sec-WebSocket-Key: /C9ah/z+wAo4mnoACSz2IA==
    < Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
    < X-Original-URL: /app
    < X-Forwarded-For: [::1]:52798
    < X-ARR-LOG-ID: 8c59749a-4e5d-43cf-8a5a-c4421cc4ecc8
    < X-P2P-PeerDist: Version=1.1
    < X-P2P-PeerDistEx: MinContentInformation=1.0, MaxContentInformation=2.0
    > HTTP/1.1 101 Switching Protocols
    > Upgrade: websocket
    > Connection: Upgrade
    > Sec-WebSocket-Accept: W9Sttf7fHX3aB9zd4b/PVGt0Ldg=
    > Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=12; client_max_window_bits=12
    > Date: Fri, 15 Jul 2022 19:14:32 GMT
    > Server: Python/3.7 websockets/10.3
    connection open
    = connection is OPEN
    ! failing connection with code 1006
    = connection is CLOSED
    x half-closing TCP connection
    connection handler failed
    Traceback (most recent call last):
      File "C:\Users\amin.ramezanifar\AppData\Roaming\Python\Python37\site-packages\websockets\legacy\protocol.py", line 945, in transfer_data
        message = await self.read_message()
      File "C:\Users\amin.ramezanifar\AppData\Roaming\Python\Python37\site-packages\websockets\legacy\protocol.py", line 1015, in read_message
        frame = await self.read_data_frame(max_size=self.max_size)
      File "C:\Users\amin.ramezanifar\AppData\Roaming\Python\Python37\site-packages\websockets\legacy\protocol.py", line 1090, in read_data_frame
        frame = await self.read_frame(max_size)
      File "C:\Users\amin.ramezanifar\AppData\Roaming\Python\Python37\site-packages\websockets\legacy\protocol.py", line 1149, in read_frame
        extensions=self.extensions,
      File "C:\Users\amin.ramezanifar\AppData\Roaming\Python\Python37\site-packages\websockets\legacy\framing.py", line 70, in read
        data = await reader(2)
      File "C:\Program Files\Python37\lib\asyncio\streams.py", line 677, in readexactly
        raise IncompleteReadError(incomplete, n)
    asyncio.streams.IncompleteReadError: 0 bytes read on a total of 2 expected bytes
    The above exception was the direct cause of the following exception:
    Traceback (most recent call last):
      File "C:\Users\amin.ramezanifar\AppData\Roaming\Python\Python37\site-packages\websockets\legacy\server.py", line 232, in handler
        await self.ws_handler(self)
      File "D:/Robotic Framework/RoboticApps/UI_Framework/server.py", line 12, in echo
        async for message in websocket:
      File "C:\Users\amin.ramezanifar\AppData\Roaming\Python\Python37\site-packages\websockets\legacy\protocol.py", line 482, in __aiter__
        yield await self.recv()
      File "C:\Users\amin.ramezanifar\AppData\Roaming\Python\Python37\site-packages\websockets\legacy\protocol.py", line 553, in recv
        await self.ensure_open()
      File "C:\Users\amin.ramezanifar\AppData\Roaming\Python\Python37\site-packages\websockets\legacy\protocol.py", line 921, in ensure_open
        raise self.connection_closed_exc()
    websockets.exceptions.ConnectionClosedError: no close frame received or sent
    connection closed
    

    To make sure if IIS settings are correct, I used another websocket library named "simple-websocket-server" from here and it worked fine. Also I tried a simple Node.js server from here and it was successful.
    What could be wrong?

    This exception means that the WebSocket connection was closed without receiving and sending a close frame, Please check the relevant information. – samwu Jul 19, 2022 at 2:08 Do you think this is an issue with the websokets module or IIS setting configurations are not right? – afar Jul 19, 2022 at 16:37

    Amin (question author) and I figured out that you have to disable compression in websockets because IIS doesn't support it.

    It worked with other libraries because they don't implement compression or don't enable it by default, unlike websockets.

    For details, see the discussion on GitHub: https://github.com/aaugustin/websockets/issues/1192

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.