Giter Club home page Giter Club logo

signalrcore's Introduction

SignalR core client

Donate Pypi Downloads Downloads Issues Open issues codecov.io

logo alt

Links

Develop

Test server will be avaiable in here and docker compose is required.

git clone https://github.com/mandrewcito/signalrcore-containertestservers
cd signalrcore-containertestservers
docker-compose up
cd ../signalrcore
make tests

Known Issues

Issues related with closing sockets are inherited from the websocket-client library. Due to these problems i can't update the library to versions higher than websocket-client 0.54.0. I'm working to solve it but for now its patched (Error number 1. Raises an exception, and then exception is treated for prevent errors). If I update the websocket library I fall into error number 2, on local machine I can't reproduce it but travis builds fail (sometimes and randomly :()

A Tiny How To

Connect to a server without auth

hub_connection = HubConnectionBuilder()\
    .with_url(server_url)\
    .configure_logging(logging.DEBUG)\
    .with_automatic_reconnect({
        "type": "raw",
        "keep_alive_interval": 10,
        "reconnect_interval": 5,
        "max_attempts": 5
    }).build()

Connect to a server with auth

login_function must provide auth token

hub_connection = HubConnectionBuilder()\
            .with_url(server_url,
            options={
                "access_token_factory": login_function,
                "headers": {
                    "mycustomheader": "mycustomheadervalue"
                }
            })\
            .configure_logging(logging.DEBUG)\
            .with_automatic_reconnect({
                "type": "raw",
                "keep_alive_interval": 10,
                "reconnect_interval": 5,
                "max_attempts": 5
            }).build()

Unauthorized errors

A login function must provide an error controller if authorization fails. When connection starts, if authorization fails exception will be propagated.

    def login(self):
        response = requests.post(
            self.login_url,
            json={
                "username": self.email,
                "password": self.password
                },verify=False)
        if response.status_code == 200:
            return response.json()["token"]
        raise requests.exceptions.ConnectionError()

    hub_connection.start()   # this code will raise  requests.exceptions.ConnectionError() if auth fails

Configure logging

HubConnectionBuilder()\
    .with_url(server_url,
    .configure_logging(logging.DEBUG)
    ...

Configure socket trace

HubConnectionBuilder()\
    .with_url(server_url,
    .configure_logging(logging.DEBUG, socket_trace=True) 
    ... 

Configure your own handler

 import logging
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
hub_connection = HubConnectionBuilder()\
    .with_url(server_url, options={"verify_ssl": False}) \
    .configure_logging(logging.DEBUG, socket_trace=True, handler=handler)
    ...

Configuring reconnection

After reaching max_attempts an exeption will be thrown and on_disconnect event will be fired.

hub_connection = HubConnectionBuilder()\
    .with_url(server_url)\
    ...
    .build()

Configuring additional headers

hub_connection = HubConnectionBuilder()\
            .with_url(server_url,
            options={
                "headers": {
                    "mycustomheader": "mycustomheadervalue"
                }
            })
            ...
            .build()

Configuring additional querystring parameters

server_url ="http.... /?myquerystringparam=134&foo=bar"
connection = HubConnectionBuilder()\
            .with_url(server_url,
            options={
            })\
            .build()

Congfiguring skip negotiation

hub_connection = HubConnectionBuilder() \
        .with_url("ws://"+server_url, options={
            "verify_ssl": False,
            "skip_negotiation": False,
            "headers": {
            }
        }) \
        .configure_logging(logging.DEBUG, socket_trace=True, handler=handler) \
        .build()

Configuring ping(keep alive)

keep_alive_interval sets the seconds of ping message

hub_connection = HubConnectionBuilder()\
    .with_url(server_url)\
    .configure_logging(logging.DEBUG)\
    .with_automatic_reconnect({
        "type": "raw",
        "keep_alive_interval": 10,
        "reconnect_interval": 5,
        "max_attempts": 5
    }).build()

Configuring logging

hub_connection = HubConnectionBuilder()\
    .with_url(server_url)\
    .configure_logging(logging.DEBUG)\
    .with_automatic_reconnect({
        "type": "raw",
        "keep_alive_interval": 10,
        "reconnect_interval": 5,
        "max_attempts": 5
    }).build()

Configure messagepack

from signalrcore.protocol.messagepack_protocol import MessagePackHubProtocol

HubConnectionBuilder()\
            .with_url(self.server_url, options={"verify_ssl":False})\
                ... 
            .with_hub_protocol(MessagePackHubProtocol())\
                ...
            .build()

Events

On Connect / On Disconnect

on_open - fires when connection is opened and ready to send messages on_close - fires when connection is closed

hub_connection.on_open(lambda: print("connection opened and handshake received ready to send messages"))
hub_connection.on_close(lambda: print("connection closed"))

On Hub Error (Hub Exceptions ...)

hub_connection.on_error(lambda data: print(f"An exception was thrown closed{data.error}"))

Register an operation

ReceiveMessage - signalr method print - function that has as parameters args of signalr method

hub_connection.on("ReceiveMessage", print)

Sending messages

SendMessage - signalr method username, message - parameters of signalrmethod

    hub_connection.send("SendMessage", [username, message])

Sending messages with callback

SendMessage - signalr method username, message - parameters of signalrmethod

    send_callback_received = threading.Lock()
    send_callback_received.acquire()
    self.connection.send(
        "SendMessage", # Method
        [self.username, self.message], # Params
        lambda m: send_callback_received.release()) # Callback
    if not send_callback_received.acquire(timeout=1):
        raise ValueError("CALLBACK NOT RECEIVED")

Requesting streaming (Server to client)

hub_connection.stream(
            "Counter",
            [len(self.items), 500]).subscribe({
                "next": self.on_next,
                "complete": self.on_complete,
                "error": self.on_error
            })

Client side Streaming

from signalrcore.subject import  Subject

subject = Subject()

# Start Streaming
hub_connection.send("UploadStream", subject)

# Each iteration
subject.next(str(iteration))

# End streaming
subject.complete()

Full Examples

Examples will be avaiable here It were developed using package from aspnet core - SignalRChat

Chat example

A mini example could be something like this:

import logging
import sys
from signalrcore.hub_connection_builder import HubConnectionBuilder


def input_with_default(input_text, default_value):
    value = input(input_text.format(default_value))
    return default_value if value is None or value.strip() == "" else value


server_url = input_with_default('Enter your server url(default: {0}): ', "wss://localhost:44376/chatHub")
username = input_with_default('Enter your username (default: {0}): ', "mandrewcito")
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
hub_connection = HubConnectionBuilder()\
    .with_url(server_url, options={"verify_ssl": False}) \
    .configure_logging(logging.DEBUG, socket_trace=True, handler=handler) \
    .with_automatic_reconnect({
            "type": "interval",
            "keep_alive_interval": 10,
            "intervals": [1, 3, 5, 6, 7, 87, 3]
        }).build()

hub_connection.on_open(lambda: print("connection opened and handshake received ready to send messages"))
hub_connection.on_close(lambda: print("connection closed"))

hub_connection.on("ReceiveMessage", print)
hub_connection.start()
message = None

# Do login

while message != "exit()":
    message = input(">> ")
    if message is not None and message != "" and message != "exit()":
        hub_connection.send("SendMessage", [username, message])

hub_connection.stop()

sys.exit(0)

signalrcore's People

Contributors

anbaalo avatar bmc-msft avatar deng2016 avatar droserasprout avatar fernanortega avatar georgik avatar lhotamir avatar mandrewcito avatar martinvol avatar morpheus65535 avatar sillydan1 avatar smiddle avatar synapticarbors avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

signalrcore's Issues

Synchronization with official semantic definitions

After I saw the example and finished the practical operation, I felt it was quite different from the official semantics

Using c # of Microsoft. AspNetCore. SignalR. Client, for example. The connection code is as follows

Connection = new HubConnectionBuilder()
          .WithUrl("http://localhost:55563/imessage/chart", (option) =>
{
     option.AccessTokenProvider = () => Task.Run(() => access_token);
 
}).Build();

Typescript connection example:

    this.hubConnection = new signalR.HubConnectionBuilder()
      .withUrl('http://localhost:55563/imessage/chart', {
        accessTokenFactory: () => this.tokenService.get().token
      }).build();

With this semantic definition, most developers can seamlessly migrate any language and use signalr.
All attribute method operations are basically the same

Doesn't work with https

Describe the bug
It doesn't work when hub server is running on https and getting following error:
scheme https is invalid <class 'ValueError'>

I am connecting it with ws://mychathost/chatHub, so if my chatHub is running on http then its working fine, but not on https.

Additional context
version: signalrcore 0.7.6

MessagePack support

As far as I can see you currently only have support for JSON serialization format. I would love to also have this library support MessagePack.
It should also be fairly easy to add as @Apollo3zehn already implemented an async fork of your repo supporting MessagePack. I could of course also use his fork directly, but I didnt want to have the async part of his code. Thus I think a backport of his work would be very good.
If everyone agrees, I can also do the PR for this repo based on the work of @Apollo3zehn.

no https support in 0.8.7?

from signalrcore.hub_connection_builder import HubConnectionBuilder
import time;

hub = HubConnectionBuilder().with_url("https://socket-v3.bittrex.com/signalr", options={"verify_ssl": False}).with_automatic_reconnect({
"type": "interval",
"keep_alive_interval": 10,
"intervals": [1, 3, 5, 6, 7, 87, 3]
}).build();

def on_open():
	print("open");

def on_close():
	print("close");

hub.on_open(on_open);
hub.on_close(on_close);
hub.start();

while True:
	time.sleep(1);

this should, according to issue #14 work, but it doesn't, I also get the

scheme https is invalid <class 'ValueError'>

websocket-client is 0.54.0

edit: the only reason why I used ws-client 0.54.0 is because it says so in the readme, however signalr core installs ws-client 0.57 by default, as the requirements for it are websocket-client>=0.54.0 for some reason

Is this project dead?

It has been a very long time since the last commit. If the project has been abandoned, it might be time to officially declare it, and maybe find someone what wants/are able to maintain it.

'NoneType' object has no attribute 'connected'

Describe the bug
With python3.8, signalrcore 0.9.2 and websocket-client 0.54.0 test socket closes almost immediately with:
Websocket closing error: issuehttps://github.com/websocket-client/websocket-client/issues/449

To Reproduce
Steps to reproduce the behavior:

  1. Install signalrcore on linux
  2. Run this example: https://api.tzkt.io/#section/Python-simple-client
  3. Socket closes after about 2 events with error
    Websocket closing error: issuehttps://github.com/websocket-client/websocket-client/issues/449

Expected behavior
I read the known issue, but I am running the version indicated (0.54.0).

Desktop (please complete the following information):

  • OS: Ubuntu 18.04
  • Version 0.9.2

Can't access classes from package after installing in venv with pip

Description
After running pip install signalrcore in the venv of my project and all requirements for download are met, signalrcore is not recognized as a package, and I can't use its functions by [dot] functionality.

To Reproduce

  1. In your venv of your project type on the terminal pip install signalrcore
  2. Import signalrcore to your script
  3. Type 'signalrcore.' on your script and no suggestions are given.

Expected behavior
A list of method suggestions should be given.

Screenshots
image
image

Desktop (please complete the following information):

  • Windows 10
  • Pycharm IDE
  • Version 2020.1

Additional context
The package is not recognized as a package but as a folder by the IDE, as shown in the screenshot.

Message Received issue when server is hosted in azure

I have a signalr server working locally and the py lib is receiving and executing the "OnConnected" callback OK.

hub_connection.on("OnConnected", onConnected)
def onConnected(result):
    print("onConnected Executed")

But when this same server is hosted in azure (slower connection and https), the OnConnected Callback does not execute in the client.

Here is the socket_trace when server is hosted locally, and with the callback working:

2020-10-13 12:15:13,193 - SignalRCoreClient - DEBUG - -- web socket open --
2020-10-13 12:15:13,203 - SignalRCoreClient - DEBUG - Sending message <signalrcore.messages.handshake.request.HandshakeRequestMessage object at 0x000001E12E7B4F60>
2020-10-13 12:15:13,209 - SignalRCoreClient - DEBUG - {"protocol": "json", "version": 1}
2020-10-13 12:15:13,219 - websocket - DEBUG - send: b'\x81\xa3h!\x03P\x13\x03s"\x07Ul3\x07M!jH\x03i#\x07O!|H\x03u5\x1aRj?\x06\x039pY\\\x1d'
2020-10-13 12:15:13,247 - SignalRCoreClient - DEBUG - Message received{}
2020-10-13 12:15:13,253 - SignalRCoreClient - DEBUG - Evaluating handshake {}
connection opened and handshake received ready to send messages
2020-10-13 12:15:13,282 - SignalRCoreClient - DEBUG - Message received{"type":1,"target":"OnConnected","arguments":["Ff78p4MwJDZlXX5iW-9IdQ","{\r\n  \"FriendlyId\": \"//DESKTOP-Q5VIKIO/ant-ipc-server\",\r\n  \"ComputerName\": \"DESKTOP-Q5VIKIO\",\r\n  \"Version\": \"2.4.5\",\r\n  \"OSPlatformName\": \"Windows\",\r\n  \"OSVersion\": \"Microsoft Windows NT 6.2.9200.0\"\r\n}"]}
2020-10-13 12:15:13,289 - SignalRCoreClient - DEBUG - Raw message incomming: 
2020-10-13 12:15:13,294 - SignalRCoreClient - DEBUG - {"type":1,"target":"OnConnected","arguments":["Ff78p4MwJDZlXX5iW-9IdQ","{\r\n  \"FriendlyId\": \"//DESKTOP-Q5VIKIO/ant-ipc-server\",\r\n  \"ComputerName\": \"DESKTOP-Q5VIKIO\",\r\n  \"Version\": \"2.4.5\",\r\n  \"OSPlatformName\": \"Windows\",\r\n  \"OSVersion\": \"Microsoft Windows NT 6.2.9200.0\"\r\n}"]}
onConnected Executed

Here is the same socket_trace when server is hosted in azure, the trace shows a MessageReceived but the OnConnected is not executing:

2020-10-13 12:15:42,451 - SignalRCoreClient - DEBUG - -- web socket open --
2020-10-13 12:15:42,457 - SignalRCoreClient - DEBUG - Sending message <signalrcore.messages.handshake.request.HandshakeRequestMessage object at 0x000001DFB1B14710>
2020-10-13 12:15:42,468 - SignalRCoreClient - DEBUG - {"protocol": "json", "version": 1}
2020-10-13 12:15:42,474 - websocket - DEBUG - send: b'\x81\xa3\x9f\xf4.\x99\xe4\xd6^\xeb\xf0\x80A\xfa\xf0\x98\x0c\xa3\xbf\xd6D\xea\xf0\x9a\x0c\xb5\xbf\xd6X\xfc\xed\x87G\xf6\xf1\xd6\x14\xb9\xae\x890'
2020-10-13 12:15:42,542 - SignalRCoreClient - DEBUG - Message received{}{"type":1,"target":"OnConnected","arguments":["6klZZBVJu6nArTSofgT04w","{\r\n  \"FriendlyId\": \"//RD281878EF439C/ant-ipc-server\",\r\n  \"ComputerName\": \"RD281878EF439C\",\r\n  \"Versio
n\": \"2.4.5\",\r\n  \"OSPlatformName\": \"Windows\",\r\n  \"OSVersion\": \"Microsoft Windows NT 10.0.14393.0\"\r\n}"]}
2020-10-13 12:15:42,549 - SignalRCoreClient - DEBUG - Evaluating handshake {}{"type":1,"target":"OnConnected","arguments":["6klZZBVJu6nArTSofgT04w","{\r\n  \"FriendlyId\": \"//RD281878EF439C/ant-ipc-server\",\r\n  \"ComputerName\": \"RD281878EF439C\",\r\n  \"V
ersion\": \"2.4.5\",\r\n  \"OSPlatformName\": \"Windows\",\r\n  \"OSVersion\": \"Microsoft Windows NT 10.0.14393.0\"\r\n}"]}
connection opened and handshake received ready to send messages

Not receiving return value from called Hub method

Thanks for your work.

I have .net core server (hub methods) running.
when client call the HUB methods then I am returning some value to the caller (client) form hub method.

but I am not receiving the same (returned value) at the client-side except None.

please advise.

Create proxy hub / invoke method

Hi,

Thanks for making this code!

I'm trying to connect to a signalr server and in the docs it says this:

To connect to the v3 socket, create a HubConnection to the socket URL ( https://socket-v3.bittrex.com/signalr) and create a hub proxy.

Then they say (without more):

To subscribe to one or more streams, simply invoke the Subscribe method

My questions are: could you please supply examples in your documentation that help with:

  1. Creating a hub "proxy", and
  2. how to "simply invoke" a method?

Many thanks!

Ytsen.

How to set the longpooling

Is your feature request related to a problem? Please describe.
I just want to set signalR to longpooling.
Could you please help me out in this.
Regards,
Srinivas Padilam

Possibility to have custom query string argument

Is your feature request related to a problem? Please describe.
I'm trying to connect to a SignalR feed that require the use of an apikey parameters to be passed as a query string argument (?apikey=abc123...).

Describe the solution you'd like
Would be great to have a qs attribute for the HubConnectionBuilder class.

Describe alternatives you've considered
I've tried to append the apikey argument to my server_url but I get this error:
Handshake status 400 Bad Request <class 'websocket._exceptions.WebSocketBadStatusException'>

Additional context
Thanks for this great module!

BaseHubConnection object has no attribute 'sock' when exiting

Describe the bug
After I conncted successfully to my personal experimental hub, each time I exit (by typing a message "exit()"), I get the following failure:

['kkkk', '']
exit()
Traceback (most recent call last):
File "SignalrClient.py", line 28, in
hub_connection.stop()
File "/signalrcore/signalrcore/hub_connection_builder.py", line 160, in stop
self._hub.stop()
File "/signalrcore/signalrcore/hub/base_hub_connection.py", line 71, in stop
self.close()
File "/usr/local/lib/python3.8/site-packages/websocket_client-0.56.0-py3.8.egg/websocket/_app.py", line 162, in close
if self.sock:
AttributeError: 'BaseHubConnection' object has no attribute 'sock'
$


To Reproduce
Steps to reproduce the behavior:

  1. See my repo
  2. Instead of running the python, you can just run it using containerized docker:
    docker run --rm -it meirkr/signalr_python
  3. When done chatting, type the message "exit()"
  4. See error

Expected behavior
Exit the app without error.

Desktop (please complete the following information):

  • OS: any os running pyhon 3 or docker

Incorrect comment in HubConnectionBuilder.build

    def build(self):
        """Configures the connection hub
        ...
        Returns:
            [HubConnectionBuilder]: [self object for fluent interface purposes]
        """

This no longer returns the self object since the method was refactored to return the HubConnection directly.

send method use same uuid str eveytime. cause incorrect CompletionMessage.

Describe the bug

def send(self, method, arguments, on_invocation=None, invocation_id=str(uuid.uuid4())) -> InvocationResult:

invocation_id=str(uuid.uuid4())
this code will generate a uuid str just only once.

To Reproduce
print( invocation_id), and call send method without specify ‘invocation_id’.

def on_open():
    print("signalr open")
    client.send("ClearWatch", [])

    def call_back(result: CompletionMessage):
        # print("callback")
        # print(result.type)
        # print(result.invocation_id)
        # print(result.error)
        # print(result.result)
        pass

    client.send("WatchOnPLC", [[]], call_back)
PS D:\Github\signalrcore> python .\test.py
signalr open
7ebd47dd-1401-4e55-beb0-9de07fbfd539
7ebd47dd-1401-4e55-beb0-9de07fbfd539

Desktop (please complete the following information):

  • OS: win11 python 3.10.4

signalrcore client doesn't work with Python2.7

The example code and the signalrcore library itself don't work in Python 2.7.

First issue:
The example code contains a callback function print. This is not supported in Python 2.7. However this is easy to solve by just changing this into a self made callback function.

Second issue:
More important, the signalrcore library cannot be imported in a Python 2.7 context. So for example the first statement in the example code:

from signalrcore.hub_connection_builder import HubConnectionBuilder

will result in this error:

Traceback (most recent call last):
  File "websocket_example.py", line 1, in <module>
    from signalrcore.hub_connection_builder import HubConnectionBuilder
  File "C:\Python27\lib\site-packages\signalrcore\hub_connection_builder.py", line 4, in <module>
    from .hub.auth_hub_connection import AuthHubConnection
  File "C:\Python27\lib\site-packages\signalrcore\hub\auth_hub_connection.py", line 4, in <module>
    from .errors import UnAuthorizedHubError, HubError
  File "C:\Python27\lib\site-packages\signalrcore\hub\errors.py", line 1, in <module>
    class HubError(ConnectionError):
NameError: name 'ConnectionError' is not defined

ConnectionError is a standard exception in Python3, but not in Python2.

To Reproduce

  1. make sure both Python v2.7 and Python v3.7 versions are installed on your system
  2. make sure the signalrcore client library is installed for both versions
  3. run example code in Python3 context:
C:\project\websocket>py -3 websocket_example.py
Enter your server url(default: ws://localhost:62342/chathub):

This is OK

  1. run example code in Python2 context:
C:\project\websocket>py -2 websocket_example.py
Traceback (most recent call last):
  File "websocket_example.py", line 1, in <module>
    from signalrcore.hub_connection_builder import HubConnectionBuilder
  File "C:\Python27\lib\site-packages\signalrcore\hub_connection_builder.py", line 4, in <module>
    from .hub.auth_hub_connection import AuthHubConnection
  File "C:\Python27\lib\site-packages\signalrcore\hub\auth_hub_connection.py", line 4, in <module>
    from .errors import UnAuthorizedHubError, HubError
  File "C:\Python27\lib\site-packages\signalrcore\hub\errors.py", line 1, in <module>
    class HubError(ConnectionError):
NameError: name 'ConnectionError' is not defined

This is clearly NOK

Expected behavior
Library should work in both Python2 and Python3 context as also stated by the pypi website: https://pypi.org/project/signalrcore/

Desktop:

  • OS: Windows 7 Pro

-

Solved

I'm getting BadRequest on IIS

Describe the bug
I have Dot Net Core 2.2 SignalR Socket Server Project.
I'am hosting my project;
Windows Version: Server 2016 Version 1607 Build 14393.3443
IIS Version: 10.0.14393.0
Successfuly connected C# Client, Javascript Client and Pyhton Client.

I'am hosting my project;
Windows Version: 10 v1903 Build 18362.592
IDE: Visual Studio Comminity 2019 With IIS Express
Successfuly connected C# Client, Javascript Client and Pyhton Client.

I'am hosting my project;
Windows Version: Server 2019 Version 1809 Build 17763.973
IIS Version: 10.0.17763.1
Successfully connected C# Client, Javascript Client. But Pyhton Client getting Status Code: 400 (Bad Request) I don't know why?

Screenshots

intermittent issue faced. any solution to this?

2021-10-26 15:02:51,606 : ERROR : Traceback (most recent call last):
File "websocket_app.py", line 306, in run_forever
File "websocket_app.py", line 53, in read
File "websocket_app.py", line 272, in read
File "websocket_core.py", line 344, in recv_data_frame
File "websocket_core.py", line 378, in recv_frame
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine

` server_url = conf['SignalHubUrl']

        handler = logging.StreamHandler()

        handler.setLevel(logging.DEBUG)

        hub_connection = HubConnectionBuilder() \

            .with_url(server_url) \

            .configure_logging(logging.DEBUG, socket_trace=False,handler=handler) \

            .with_automatic_reconnect({

            "type": "interval",

            "keep_alive_interval": 10,

            "reconnect_interval": 5,

            "max_attempts": 50

        }).build()



        hub_connection.on_open(lambda: print("connection opened and handshake received ready to receive messages"))



        hub_connection.start()



        hub_connection.on("APINotificationGeo_worker_multi", self.api_signalling)`

A way to handle messages without event?

I'm looking through the examples and source code but I can't seem to get an idea of how to do this. I send my message using the following:

hub_connection.send( "GetMessages", arguments=[""], on_invocation=on_success )

This works fine and from here I am expecting a couple of messages:

Raw message incomming:
Message received{"type":3,"invocationId":"77e18329-dae3-4893-a4a9-d5ba7f891575","result":null
Raw message incomming:
Message received{"type":3,"invocationId":"0d53d44a-82ff-4695-bd8e-91bbb25731fa","result":[...snipped data]

My send message results in the server sending two messages, which I successfully receive by looking at trace. I can handle the first message fine via "on_invocation" function (I can print the result and show that it is None). However; I can't seem to intercept the second request which does not have an empty "result".

Is there a way to intercept multiple requests in the on_invocation function or a way to manually handle the raw messages received?

ASPNET 5.0: Reconnection tests failing

Describe the bug
Test on reconnect fail with aspnet 5.0

======================================================================
FAIL: test_raw_reconnection (reconnection_test.TestReconnectMethods)

Traceback (most recent call last):
File "/mnt/d/mandrewcito/signalrcore/test/reconnection_test.py", line 127, in test_raw_reconnection
self.reconnect_test(connection)
File "/mnt/d/mandrewcito/signalrcore/test/reconnection_test.py", line 106, in reconnect_test
self.assertTrue(_lock.acquire(timeout=30))
AssertionError: False is not true

======================================================================
FAIL: test_reconnect_interval (reconnection_test.TestReconnectMethods)

Traceback (most recent call last):
File "/mnt/d/mandrewcito/signalrcore/test/reconnection_test.py", line 58, in test_reconnect_interval
self.reconnect_test(connection)
File "/mnt/d/mandrewcito/signalrcore/test/reconnection_test.py", line 106, in reconnect_test
self.assertTrue(_lock.acquire(timeout=30))
AssertionError: False is not true


Ran 55 tests in 184.478s

Reference to undefined function `_send_ping`

In perusing the source code for this library I noticed that there is a call to a method of the BaseHubConnection called _send_ping()

This function is not defined within the source code and as far as I can tell, was never defined (searching through the git history).

I'm guessing it should probably be replaced by something like self.send(PingMessage()). I can open a pull request if this seems reasonable.

SignalRCore + Azure SignalR howto

Is your feature request related to a problem? Please describe.
A clear example how to connect to a named service, e.g. Azure SignalR

Describe the solution you'd like
Setting up a SignalR service in Azure is trivial. What you get is a connection string with hostname and primary key. It is unclear how this needs to be configured using signalrcore to establish a connection to the service. A "Azure + SignalRCore step-by-step" -guide would solve the problem (and help signalrcore adoption greatly)

Describe alternatives you've considered
I've tried to configure this in various ways, but all seems to fail.

Feature: Support .net allowReconnect type

Is your feature request related to a problem? Please describe.
Feature to handle when the server allows for a reconnect when the server sends allowReconnect

image

https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/HubProtocol.md#close-message-encoding

Describe the solution you'd like
Allow for the client to either automatically reconnect or to have and event that allows the developer to take action

Describe alternatives you've considered
none

Additional context
image

The headers variable initialization method is not correct. In the case of multiple threads, headersr of multiple instances points to the same memory address, causing tokens to overwrite each other

Describe the bug
In the HubConnectionBuilder, AuthHubConnection, BaseHubConnection and other three classes, the way to initialize the headers variable is:
headers={}

It is normal to use in a single thread, but when used in multiple threads, all headers point to the same memory address, which will cause the token to be overwritten by the last object.

// Comparison of the two initialization methods of the dictionary 
// {}
print(id({}))
print(id({}))
print(id({}))

// dict()
print(id(dict()))
print(id(dict()))
print(id(dict()))

/* Post run output
1984312275072
1984312275072
1984312275072
1984315991552
1984315990848
1984316002560
*/

Sever-Sent-Events (SSE) connection problem

I have a problem with Sever-Sent-Events (SSE).
The server we used does not support websocket. so we need to connect as Sever-Sent-Events (SSE). Can we connect with Sever-Sent-Events (SSE) other than websocket? Thank you very much in advance for your answer.

attempt to invoke method returns InvalidDataException: Missing required property

I've made test method to check python client but cannot manage to invoke it:
During attempt to invoke method server returns InvalidDataException: Missing required property ...

my back-end is asp.net core 3.1 this way I've got
Microsoft.AspNetCore.SignalR 3.100.320.12812

on attempt to call simple server method

public void ReceiveString(string t1, string t2)
{
  Logger.LogInformation(t1);
  Logger.LogInformation(t2);
}

like

print("starting")
hub_connection.start()

print("sending")
hub_connection.send("ReceiveString", ["test1", "test2"])

input('hit Enter to stop')
print("stopping")
hub_connection.stop()

I've got

starting
2020-08-27 18:59:38,276 - SignalRCoreClient - DEBUG - Starting connection ...
2020-08-27 18:59:38,680 - SignalRCoreClient - DEBUG - auth function result eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6IjEiLCJ1bmlxdWVfbmFtZSI6ImZpdHRlciIsImxhc3RDaGFuZ2VkIjoiMDEtSmFuLTAxIDAwOjAwOjAwIiwibmJmIjoxNTk4NTQzOTc4LCJleHAiOjE1OTg1NzI3NzgsImlhdCI6MTU5ODU0Mzk3OCwiaXNzIjoiZnNnY29yZS5hcGkifQ._d1DxRxOmNgNJtNxvw9arKzMyxPmKiV2suG-KEdxhmg
2020-08-27 18:59:38,680 - SignalRCoreClient - DEBUG - Negotiate url:http://localhost:5000/hubs/video/negotiate?sessionKey=4f55d24c-e87e-11ea-a62a-4ccc6ade4fdf
2020-08-27 18:59:38,781 - SignalRCoreClient - DEBUG - Response status code200
2020-08-27 18:59:38,781 - SignalRCoreClient - DEBUG - Connection started
2020-08-27 18:59:38,782 - SignalRCoreClient - DEBUG - start url:ws://localhost:5000/hubs/video?sessionKey=4f55d24c-e87e-11ea-a62a-4ccc6ade4fdf&id=8Tc8LNROqmKfeiZVq5FgzA
sending
2020-08-27 18:59:38,783 - SignalRCoreClient - DEBUG - Sending message InvocationMessage: invocation_id a5a02233-94ff-45bc-bc17-f84f8cc57f81, target ReceiveString, arguments ['test1', 'test2']
2020-08-27 18:59:38,783 - SignalRCoreClient - DEBUG - {"type": 1, "headers": {}, "target": "ReceiveString", "arguments": ["test1", "test2"], "invocationId": "a5a02233-94ff-45bc-bc17-f84f8cc57f81"}�
hit Enter to stop
2020-08-27 18:59:38,809 - SignalRCoreClient - DEBUG - -- web socket open --
2020-08-27 18:59:38,810 - SignalRCoreClient - DEBUG - Sending message <signalrcore.messages.handshake.request.HandshakeRequestMessage object at 0x000001F39A30A088>
2020-08-27 18:59:38,810 - SignalRCoreClient - DEBUG - {"protocol": "json", "version": 1}�
2020-08-27 18:59:38,828 - SignalRCoreClient - DEBUG - Message received{"error":"An unexpected error occurred during connection handshake. InvalidDataException: Missing required property \u0027protocol\u0027. Message content: {\u0022type\u0022: 1, \u0022headers\u0022: {}, \u0022target\u0022: \u0022ReceiveString\u0022, \u0022arguments\u0022: [\u0022test1\u0022, \u0022test2\u0022], \u0022invocationId\u0022: \u0022a5a02233-94ff-45bc-bc17-f84f8cc57f81\u0022}"}�
2020-08-27 18:59:38,829 - SignalRCoreClient - DEBUG - Evaluating handshake {"error":"An unexpected error occurred during connection handshake. InvalidDataException: Missing required property \u0027protocol\u0027. Message content: {\u0022type\u0022: 1, \u0022headers\u0022: {}, \u0022target\u0022: \u0022ReceiveString\u0022, \u0022arguments\u0022: [\u0022test1\u0022, \u0022test2\u0022], \u0022invocationId\u0022: \u0022a5a02233-94ff-45bc-bc17-f84f8cc57f81\u0022}"}�
2020-08-27 18:59:38,829 - SignalRCoreClient - ERROR - An unexpected error occurred during connection handshake. InvalidDataException: Missing required property 'protocol'. Message content: {"type": 1, "headers": {}, "target": "ReceiveString", "arguments": ["test1", "test2"], "invocationId": "a5a02233-94ff-45bc-bc17-f84f8cc57f81"}
2020-08-27 18:59:38,836 - SignalRCoreClient - DEBUG - -- web socket close --

as a "blunt action" I've tried to provide protocol field as json in ...\signalrcore\messages\invocation_message.py
so InvalidDataException changed to Missing required property 'version', which easy to provide the same way with value 1,
but it don't really solves or reveals the issue to me:

starting
2020-08-27 19:15:59,861 - SignalRCoreClient - DEBUG - Starting connection ...
2020-08-27 19:16:00,278 - SignalRCoreClient - DEBUG - auth function result eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJJZCI6IjEiLCJ1bmlxdWVfbmFtZSI6ImZpdHRlciIsImxhc3RDaGFuZ2VkIjoiMDEtSmFuLTAxIDAwOjAwOjAwIiwibmJmIjoxNTk4NTQ0OTYwLCJleHAiOjE1OTg1NzM3NjAsImlhdCI6MTU5ODU0NDk2MCwiaXNzIjoiZnNnY29yZS5hcGkifQ.35s8adyLT2PxjxaHAGA8YzoGPv8UHP4fFranPefefPU
2020-08-27 19:16:00,279 - SignalRCoreClient - DEBUG - Negotiate url:http://localhost:5000/hubs/video/negotiate?sessionKey=9867b094-e880-11ea-8dc2-4ccc6ade4fdf
2020-08-27 19:16:00,381 - SignalRCoreClient - DEBUG - Response status code200
2020-08-27 19:16:00,382 - SignalRCoreClient - DEBUG - Connection started
2020-08-27 19:16:00,382 - SignalRCoreClient - DEBUG - start url:ws://localhost:5000/hubs/video?sessionKey=9867b094-e880-11ea-8dc2-4ccc6ade4fdf&id=8PT04GEIKUZuspzPwz07Bg
sending
2020-08-27 19:16:00,383 - SignalRCoreClient - DEBUG - Sending message InvocationMessage: invocation_id 88afbec7-936b-4e74-802f-753cc29bafdf, target ReceiveString, arguments ['test1', 'test2']
2020-08-27 19:16:00,383 - SignalRCoreClient - DEBUG - {"type": 1, "headers": {}, "target": "ReceiveString", "arguments": ["test1", "test2"], "protocol": "json", "version": 1, "invocationId": "88afbec7-936b-4e74-802f-753cc29bafdf"}�
hit Enter to stop
2020-08-27 19:16:00,409 - SignalRCoreClient - DEBUG - -- web socket open --
2020-08-27 19:16:00,410 - SignalRCoreClient - DEBUG - Sending message <signalrcore.messages.handshake.request.HandshakeRequestMessage object at 0x0000020D711DA588>
2020-08-27 19:16:00,410 - SignalRCoreClient - DEBUG - {"protocol": "json", "version": 1}�
2020-08-27 19:16:00,428 - SignalRCoreClient - DEBUG - Message received{}�
2020-08-27 19:16:00,429 - SignalRCoreClient - DEBUG - Evaluating handshake {}�
2020-08-27 19:16:00,465 - SignalRCoreClient - DEBUG - Message received{"type":7,"error":"Connection closed with an error. InvalidDataException: Missing required property \u0027type\u0027.","allowReconnect":true}�
2020-08-27 19:16:00,465 - SignalRCoreClient - DEBUG - Raw message incomming: 
2020-08-27 19:16:00,465 - SignalRCoreClient - DEBUG - {"type":7,"error":"Connection closed with an error. InvalidDataException: Missing required property \u0027type\u0027.","allowReconnect":true}�
2020-08-27 19:16:00,465 - SignalRCoreClient - INFO - Close message received from server
2020-08-27 19:16:00,465 - SignalRCoreClient - DEBUG - Connection stop

since it starting to nagging about missing type field, which is even stranger

it might be somehow connected to similar issue some folks having with Android client: com.microsoft.signalr:signalr: 3.1.0:
Missing required property 'type'

Let me know if I can be of any assistance :)

ModuleNotFoundError: No module named 'signalrcore.transport'

Getting such an error with 0.9.1 when trying to build hub_connection.

Traceback (most recent call last):
  File "./test.py", line 1, in <module>
    from signalrcore.hub_connection_builder import HubConnectionBuilder
  File "/home/stsdc/.local/lib/python3.8/site-packages/signalrcore/hub_connection_builder.py", line 2, in <module>
    from .hub.base_hub_connection import BaseHubConnection
  File "/home/stsdc/.local/lib/python3.8/site-packages/signalrcore/hub/base_hub_connection.py", line 17, in <module>
    from ..transport.websockets.websocket_transport import WebsocketTransport
ModuleNotFoundError: No module named 'signalrcore.transport'

Not working with self hosted Asp.NET.signalR server console app

@mandrewcito
Thanks for your work.

I am trying to communicate with a self-hosted SignalR server (Not .NET CORE app) with the below sample python script but I am getting the below error

Connection closed Connection is already closed.
Handshake status 400 Bad Request <class 'websocket._exceptions.WebSocketBadStatusException'>

Both .NET (self-host console app) and .NET core ( hosted on IIS) are tested with same PC

But the same below sample python code works fine with provided ASP.Net Core SignalRChat application.

sample test code:

`Using package from aspnet core - SignalRChat example chat without auth

from signalrcore.hub_connection_builder import HubConnectionBuilder
def input_with_default(input_text, default_value):
value = input(input_text.format(default_value))
return default_value if value is None or value.strip() == "" else value

server_url = input_with_default('Enter your server url(default: {0}): ', "ws://192.168.x.y:8080/chathub")
username = input_with_default('Enter your username (default: {0}): ', "user1")

hub_connection = HubConnectionBuilder().with_url(server_url).with_automatic_reconnect({
"type": "raw",
"keep_alive_interval": 10,
"reconnect_interval": 5,
"max_attempts": 5
}).build()
hub_connection.on("ReceiveMessage", print)
hub_connection.start()
message = None
while message != "exit()":
message = input(">> ")
if message is not None and message is not "" and message is not "exit()":
hub_connection.send("SendMessage", [username, message])
hub_connection.stop()`

please advise, how to work with self-hosted application

Long Delay

We have issues connection with this code to the hub because of long latency, how could we fix this.
The client says the connection is allready closed and the hub says there is a handshake problem.

Problem with serialization

Hello, everyone!
I wanted to test your lib for using it in the prod, but i could't to send message, because it is not serialized right
I create the same client app, but on the dotnet, and all work fine.

But when i use your lib, i have a problem:

2022-04-09 16:38:18,640 - SignalRCoreClient - DEBUG - Handler registered started TestClientEvent

2022-04-09 16:38:18,642 - SignalRCoreClient - DEBUG - Connection started

2022-04-09 16:38:18,642 - SignalRCoreClient - DEBUG - Negotiate url:http://localhost:40071/test-hub/negotiate

2022-04-09 16:38:18,710 - SignalRCoreClient - DEBUG - Response status code200

2022-04-09 16:38:18,711 - SignalRCoreClient - DEBUG - start url:ws://localhost:40071/test-hub?id=FumuYZ40TqJWOVEMYe8sRA

2022-04-09 16:38:18,711 - SignalRCoreClient - DEBUG - Sending message InvocationMessage: invocation_id b0b25f8e-b8fa-4e7a-84ff-b51272f4a06e, target TestMethod, arguments [<class '__main__.subject'>]

Traceback (most recent call last):

  File "C:/Users/Сергей/PycharmProjects/pythonProject1/main.py", line 44, in <module>

    hub_connection.send("TestMethod", [subject])

  File "C:\Users\Сергей\PycharmProjects\SignalRTest\lib\site-packages\signalrcore\hub\base_hub_connection.py", line 147, in send

    self.transport.send(message)

  File "C:\Users\Сергей\PycharmProjects\SignalRTest\lib\site-packages\signalrcore\transport\websockets\websocket_transport.py", line 217, in send

    raise ex

  File "C:\Users\Сергей\PycharmProjects\SignalRTest\lib\site-packages\signalrcore\transport\websockets\websocket_transport.py", line 196, in send

    self.protocol.encode(message),

  File "C:\Users\Сергей\PycharmProjects\SignalRTest\Lib\signalrcore\protocol\messagepack_protocol.py", line 72, in encode

    encoded_message = msgpack.packb(msg)

  File "C:\Users\Сергей\PycharmProjects\SignalRTest\lib\site-packages\msgpack\__init__.py", line 35, in packb

    return Packer(**kwargs).pack(o)

  File "msgpack\_packer.pyx", line 292, in msgpack._cmsgpack.Packer.pack

  File "msgpack\_packer.pyx", line 298, in msgpack._cmsgpack.Packer.pack

  File "msgpack\_packer.pyx", line 295, in msgpack._cmsgpack.Packer.pack

  File "msgpack\_packer.pyx", line 264, in msgpack._cmsgpack.Packer._pack

  File "msgpack\_packer.pyx", line 264, in msgpack._cmsgpack.Packer._pack

  File "msgpack\_packer.pyx", line 289, in msgpack._cmsgpack.Packer._pack

TypeError: can not serialize 'type' object

Script exits too soon

I am having issues with my python script that uses signalrcore. The script works perfectly when ran from the command line but when I launch it via a shell script from a dot net core application it exits before the connection is even started.

Log when ran from command line:

Connection started
Negotiate url:https://localhost/configHub/negotiate
Response status code200
start url:wss://localhost/configHub?id=KnVEgbXhMF832U_5oSbvvg
Handler registered started ScriptFinished
Connection started
Negotiate url:https://localhost/configHub/negotiate
Response status code200
start url:wss://localhost/configHub?id=0m9YKSz01IA3qS654rGJCw
Handler registered started ScriptFinished
--- request header ---
GET /configHub?id=0m9YKSz01IA3qS654rGJCw HTTP/1.1^M
Upgrade: websocket^M
Connection: Upgrade^M
Host: localhost^M
Origin: http://localhost^M
Sec-WebSocket-Key: 5nVtvV/urzt/rj1nfG48bA==^M
Sec-WebSocket-Version: 13^M
^M


--- response header ---
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Date: Fri, 13 Aug 2021 15:13:50 GMT
Server: Kestrel
Upgrade: websocket
Sec-WebSocket-Accept: q/n/9skwZcKHBJs/K4hGbg3fNQc=

-- web socket open --
Sending message <signalrcore.messages.handshake.request.HandshakeRequestMessage object at 0x7f28fde0ab38>
{"protocol": "json", "version": 1}^^
send: b'\x81\xa3\xe8\x1d8\xc2\x93?H\xb0\x87iW\xa1\x87q\x1a\xf8\xc8?R\xb1\x87s\x1a\xee\xc8?N\xa7\x9anQ\xad\x86?\x02\xe2\xd9`&'
Message received{}^^
Evaluating handshake {}^^
Sending message InvocationMessage: invocation_id fc23fcb8-e8ce-480b-8b57-fc93987f6721, target ScriptFinished, arguments []
{"type": 1, "headers": {}, "target": "ScriptFinished", "arguments": [], "invocationId": "fc23fcb8-e8ce-480b-8b57-fc93987f6721"}^^
send: b'\x81\xfe\x00\x80\xa1\xc8\xda\x17\xda\xea\xaen\xd1\xad\xf8-\x81\xf9\xf67\x83\xa0\xbfv\xc5\xad\xa8d\x83\xf2\xfal\xdc\xe4\xfa5\xd5\xa9\xa8p\xc4\xbc\xf8-\x81\xea\x89t\xd3\xa1\xaac\xe7\xa1\xb4~\xd2\xa0\xbfs\x83\xe4\xfa5\xc0\xba\xbdb\xcc\xad\xb4c\xd2\xea\xe07\xfa\x95\xf67\x83\xa1\xb4a\xce\xab\xbbc\xc8\xa7\xb4^\xc5\xea\xe07\x83\xae\xb9%\x92\xae\xb9u\x99\xe5\xbf/\xc2\xad\xf7#\x99\xf8\xb8:\x99\xaa\xef \x8c\xae\xb9.\x92\xf1\xe2 \xc7\xfe\xed%\x90\xea\xa7\t'
Message received{"type":1,"target":"ScriptFinished","arguments":[]}^^{"type":3,"invocationId":"fc23fcb8-e8ce-480b-8b57-fc93987f6721","result":null}^^
Raw message incomming:
{"type":1,"target":"ScriptFinished","arguments":[]}^^{"type":3,"invocationId":"fc23fcb8-e8ce-480b-8b57-fc93987f6721","result":null}^^
Connection stop

Log when launched via shell script from dot net core application:

Connection started
Negotiate url:https://localhost/configHub/negotiate
Response status code200
start url:wss://localhost/configHub?id=KnVEgbXhMF832U_5oSbvvg
Handler registered started ScriptFinished

WebSocketBadStatusException: Handshake status 200 OK

I got Handshake status 200 OK instead of one success statuses.

LOGS

2020-11-16 21:37:58,797 - SignalRCoreClient - DEBUG - Handler registered started AwakeReceived_Group
2020-11-16 21:37:58,797 - SignalRCoreClient - DEBUG - Negotiate url:https://............/hubs/awake/negotiate
c:\python\lib\site-packages\urllib3\connectionpool.py:981: InsecureRequestWarning: Unverified HTTPS request is being made to host '............'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  warnings.warn(
2020-11-16 21:37:58,984 - SignalRCoreClient - DEBUG - Response status code200
2020-11-16 21:37:58,985 - SignalRCoreClient - DEBUG - Connection started
2020-11-16 21:37:58,985 - SignalRCoreClient - DEBUG - start url:wss://............/hubs/awake?id=NQZMZmxqk0q5EjPLkdNORA
2020-11-16 21:37:59,063 - websocket - DEBUG - --- request header ---
2020-11-16 21:37:59,063 - websocket - DEBUG - GET /hubs/awake?id=NQZMZmxqk0q5EjPLkdNORA HTTP/1.1
Upgrade: websocket
Host: ............
Origin: http://............
Sec-WebSocket-Key: dedr/jpAeI8mTzdqfO9gNw==
Sec-WebSocket-Version: 13
Connection: upgrade


2020-11-16 21:37:59,064 - websocket - DEBUG - -----------------------
2020-11-16 21:37:59,064 - websocket - DEBUG - --- response header ---
2020-11-16 21:37:59,084 - websocket - DEBUG - HTTP/1.1 200 OK
2020-11-16 21:37:59,084 - websocket - DEBUG - Content-Length: 0
2020-11-16 21:37:59,084 - websocket - DEBUG - Content-Type: application/octet-stream
2020-11-16 21:37:59,085 - websocket - DEBUG - Server: Microsoft-IIS/8.5
2020-11-16 21:37:59,085 - websocket - DEBUG - X-Powered-By: ASP.NET
2020-11-16 21:37:59,085 - websocket - DEBUG - Date: Mon, 16 Nov 2020 20:37:58 GMT
2020-11-16 21:37:59,085 - websocket - DEBUG - -----------------------
2020-11-16 21:37:59,086 - SignalRCoreClient - DEBUG - -- web socket error --
2020-11-16 21:37:59,092 - SignalRCoreClient - ERROR - Traceback (most recent call last):
  File "c:\python\lib\site-packages\websocket\_app.py", line 249, in run_forever
    self.sock.connect(
  File "c:\python\lib\site-packages\websocket\_core.py", line 226, in connect
    self.handshake_response = handshake(self.sock, *addrs, **options)
  File "c:\python\lib\site-packages\websocket\_handshake.py", line 80, in handshake
    status, resp = _get_resp_headers(sock)
  File "c:\python\lib\site-packages\websocket\_handshake.py", line 165, in _get_resp_headers
    raise WebSocketBadStatusException("Handshake status %d %s", status, status_message, resp_headers)
websocket._exceptions.WebSocketBadStatusException: Handshake status 200 OK

2020-11-16 21:37:59,093 - SignalRCoreClient - ERROR - <signalrcore.hub.base_hub_connection.BaseHubConnection object at 0x0000027025E8B850> Handshake status 200 OK
2020-11-16 21:37:59,093 - SignalRCoreClient - ERROR - Handshake status 200 OK <class 'websocket._exceptions.WebSocketBadStatusException'>
connection closed
2020-11-16 21:37:59,093 - websocket - ERROR - error from callback <bound method BaseHubConnection.on_socket_error of <signalrcore.hub.base_hub_connection.BaseHubConnection object at 0x0000027025E8B850>>: Handshake status 200 OK
  File "c:\python\lib\site-packages\websocket\_app.py", line 344, in _callback
    callback(*args)
  File "c:\python\lib\site-packages\signalrcore\hub\base_hub_connection.py", line 162, in on_socket_error
    raise HubError(error)
2020-11-16 21:37:59,097 - SignalRCoreClient - DEBUG - -- web socket close --
connection closed
depth mask updated

async python support

Is your feature request related to a problem? Please describe.
I have a larger async python app, and I'd like to establish signalr connections without blocking my event loop. To my best knowledge, right now using signalrcore methods would block my event loop, and thus block my entire app.

Describe the solution you'd like
There is an interface that allows me to connect and send messages asynchronously. All handlers can be asynchronous functions.

Callback on connection established

Is your feature request related to a problem? Please describe.
Since the ".start()" function takes long, my chat (demo) app starts to send messages to the server (and other clients), but no callback arrives back from the server.
I guess because the connection is still being established including handshake.

I was based on your example and made my own test app for chat.
GH: https://github.com/meirkr/signalr_pythom
To reproduce,

  1. start one or more web clients https://meirkr.com
  2. Clone my ripo above and run the code.
    OR:
    using docker:
    docker run --rm -it meirkr/signalr_python
  3. Right after inserting nick, try immediately to type some messages from that python client or even the other web clients. Sometimes it arrives fast, but sometimes (and most of times) it takes around 5-10 seconds till the messages are arrived (till then, the messages are just skipped)

Describe the solution you'd like
In angular signalr client, there is a possibility to get a trugger when the async start is completed, I assume inclusing the handshake.
this._hubConnection .start() .**then(() => this.OnConnected())** .catch(err => { this.connected = false; console.log('Error while establishing connection :(' + err); setTimeout(() => this.reconnect(), 5000); });
Is there a possibility to get something similar?

Application freezed after received message.

I'm working on desktop application based on PyQT and signalrcore library. My application freezed after recived a message from server.

Steps to reproduce the behavior:

  1. Create simple app with PyQT and signalrcore.
  2. Write code to handle messages from server
  3. In handler method call "showFullScreen()"

Expected behavior
Application should open in full screen mode.

Desktop (please complete the following information):

  • OS: Windows 10
  • Python 3.8.5 64 bit

Additional context
This situation have place only when I execute showFullScreen() from inside of message handler method.

Building connection

self.connection = HubConnectionBuilder()\
	.with_url(self.hubUrl, options=
	{
		"skip_negotiation": False,
		"verify_ssl": True,
	})\
	.configure_logging(logging.ERROR)\
	.with_automatic_reconnect({
		"type": "interval",
		"keep_alive_interval": 10,
		"intervals": [1, 3, 5, 6, 7, 87, 3]
	}).build()

self.connection.on_open(lambda: self.onOpen())
self.connection.on_close(lambda: print("---- Disconnected ----"))
self.connection.on_error(lambda data: print("---- Error ----\n{data.error}\n---------------"))

self.connection.on("AwakeReceived", lambda data: self.onAwakeReceived(data))

self.connection.start()

Message handler method

def onAwakeReceived(self, data):
	print("---- Received data ----")

	# TODO

	self.showFullScreen()

I think the reason could be related with thread uesd to handle websocket. Is there posibility to inject QThread?

websocket-client version

Describe the bug
The signalrcore lib does not work fully with websocket-client later than 0.54.0, but requirements in setup.py is not enforcing that since requirement is websocket-client>=0.54.0

To Reproduce
Steps to reproduce the behavior:

  1. Install signalr with pip.
  2. websocket-client is installed with the newest available version.

Expected behavior
signalrcore should enforce the use of a compatible version of websocket-client.

Spelling error

"Hub is not running you cand send messages" at /signalrcore/hub/base_hub_connection.py line 127 should be "Hub is not running you cannot send messages" or "Hub is not running. Unable to transmit messages". Actually, the hub might very well be running but not accessible so perhaps "Cannot connect to SignalR hub. Unable to transmit messages"

Cheers

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.