Notification 2.0 with python websockets microservice: SSL: WRONG_VERSION_NUMBER

What product/components do you use and which version/fix level are you on?

Cumulocity IoT 1015.0.278

Is your question related to the free trial, or to a production (customer) instance?

prduction: xy.cumulocity.com

What are you trying to achieve? Please describe it in detail.

Running a Python Microservice on Cumulocity IoT which uses the Notification 2.0 API

Therefore i use the websockets library with asyncio in a seperate thread, the main thread is starting a flask server.

When i run a similar python script on my local machine and connect it to the same Cumulocity IoT Tenant, it works.

This is the relevant part of the code, its the continuous listening for incoming messages:

    async def listen(self, callback: callable):
        async with websockets.connect(
            f"wss://{url}/notification2/consumer/?token={self.token}"
        ) as websocket:
            print(f"Websocket connected: {str(websocket)}")
            async for message in websocket:
                print("Received message: {}".format(message))
                await callback(message)

Do you get any error messages? Please provide a full error message screenshot and log file.

From the log in

Traceback (most recent call last):
  File "//main.py", line 82, in <module>
    listen_websocket(handle_alarms)
  File "//main.py", line 64, in listen_websocket
    asyncio.run(alarm_subscription.listen(callback))  # blocking
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 190, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/API/subscribe.py", line 79, in listen
    async with websockets.connect(
  File "/usr/local/lib/python3.11/site-packages/websockets/legacy/client.py", line 642, in __aenter__
    return await self
           ^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/websockets/legacy/client.py", line 659, in __await_impl_timeout__
    return await asyncio.wait_for(self.__await_impl__(), self.open_timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/tasks.py", line 479, in wait_for
    return fut.result()
           ^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/websockets/legacy/client.py", line 663, in __await_impl__
    _transport, _protocol = await self._create_connection()
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 1112, in create_connection
    transport, protocol = await self._create_connection_transport(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 1145, in _create_connection_transport
    await waiter
  File "/usr/local/lib/python3.11/asyncio/sslproto.py", line 574, in _on_handshake_complete
    raise handshake_exc
  File "/usr/local/lib/python3.11/asyncio/sslproto.py", line 556, in _do_handshake
    self._sslobj.do_handshake()
  File "/usr/local/lib/python3.11/ssl.py", line 979, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:992)

Have you installed all the latest fixes for the products and systems you are using?

Cumulocity IoT 1015.0.278

Hi @simeon.mendgen,

Can you use the ws:// protocol if it is run as a microservice? If that does not solve the problem, kindly send the code over so that we can take a closer look. Thanks.

Regards,
Rohit Joshi

Hi, I have one more thought. Disabling SSL may help.

Hi @simeon.mendgen,

I haven’t had that and I used wss:// without issues. Maybe the Python version?

I just wanted to point you to the cumulocity-python-api project on GitHub which recently added a reference implementation for that. It provides a wrapper that takes care about all these technical details.
Thread-based example: samples/notification2_synchronous.py (github.com)
async-io example: samples/notification2_asynchronous.py (github.com)

You could also check the implementation of said wrapper: listener.py (github.com) - I’m the maintainer of this project, would be happy to get some feedback!

1 Like

Could be anything. My assumption would be that the URL is wrong or using an external domain name.

Within C8Y you should resolve the URL by getting the env variable $C8Y_BASEURL.
Can you give it a try?

Hi thanks for all your responses,

@Stefan_Witschel
I do use the C8Y_BASEURL and strip it from https:// . To be more precise i use the Authentication class from here: authentication.py

@Christoph_Souris
I already testet with a python3.9 image and had the same error.
I will try using cumulocity-python-api, but its not that fast to test for me, have to re write a bit to work around some errors. Will PN you about this.

@yiz
I dont know if i can and want to disable SSL on the cumulocity instance if thats what you meant.

@Rohit_Joshi5
I will continue my to try out the cumulocity-python-api if this does not help me i will post my code.

Hi @simeon.mendgen

I think I got your problem. When running internally it’s a http connection so you cannot replace https:// with wss://or do a strip.
You also have to handle http:// with ws://

Java example:

baseUrl = baseUrl.replace("http", "ws");

This would also explain why it is working locally but not deployed in Cumulocity.

@Stefan_Witschel

you were totally correct, i changed

async with websockets.connect(f"wss://{url.lstrip('https://')}/notification2/consumer/?token={self.token}" ) as websocket:
               ...

to

async with websockets.connect(f"{url.replace('http','ws')}/notification2/consumer/?token={self.token}" ) as websocket:
               ...

and it works :slight_smile:

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.