SignalR core client
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)
Metadata
Release files for signalrcoreplus 0.10.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| signalrcoreplus-0.10.3.tar.gz | 24.6 kB | Without provenance | Details for signalrcoreplus-0.10.3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| signalrcoreplus-0.10.3-py3-none-any.whl | Python 3 | none | any | Details for signalrcoreplus-0.10.3-py3-none-any.whl |
Total release size: 60.5 kB
Release files / signalrcoreplus-0.10.3.tar.gz
| Download URL | signalrcoreplus-0.10.3.tar.gz |
|---|---|
| Size | 24.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3bdc1697d240d01150e0dfd58d7f10158620842e55b6a552decef78b6eb38d5d
|
|
BLAKE2b-256 checksum How to use checksums |
64ea5498299c0832a581b068c7e7cb86dc4ef580b61f414dbef010acf84f9cfd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.10.9
|
Release files / signalrcoreplus-0.10.3-py3-none-any.whl
| Download URL | signalrcoreplus-0.10.3-py3-none-any.whl |
|---|---|
| Size | 35.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
87c69c629cadc30c63d55fb7d15bbcf601ce240a763d816d64f3b4bb2dea4ae9
|
|
BLAKE2b-256 checksum How to use checksums |
80b918a33fe78904501987e00699838c5269f67bf5f6ebadbdb1b863682779ea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.10.9
|
Security for signalrcoreplus 0.10.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.