Package: signalrcorePPI
SignalR core clientLinksDev to posts with library examples and implementationPypiWiki - This DocDevelopTest server will be avaiable inhereand docker compose is required.gitclonehttps://github.com/mandrewcito/signalrcore-containertestserverscdsignalrcore-containertestservers
docker-composeupcd../signalrcore
maketestsknown issuesIssues related with closing socket inherited from websocket-client library. Due this problems i cant update library to versions higher than websocket-client 0.54.0.
I'm working for solve it, for now its patched (Error number 1. Raises an exception, and then exception is treated for prevent errors).
If i update weboscket library i fall into error number 2, on local machine i cant reproduce it but on travis builds fails (sometimes and randomly :()1. Closing socket error2. Random errors closing socketA tiny How ToConnect to a server without authhub_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 authlogin_function must provide auth tokenhub_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 errosA login function must provide a error control if authorization fails. When connection starts, if authorization fails exception will be propagued.deflogin(self):response=requests.post(self.login_url,json={"username":self.email,"password":self.password},verify=False)ifresponse.status_code==200:returnresponse.json()["token"]raiserequests.exceptions.ConnectionError()hub_connection.start()# this code will raise  requests.exceptions.ConnectionError() if auth failsConfigure loggingHubConnectionBuilder()\.with_url(server_url,.configure_logging(logging.DEBUG)...Configure socket traceHubConnectionBuilder()\.with_url(server_url,.configure_logging(logging.DEBUG,socket_trace=True)...Configure your own handlerimportlogginghandler=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 reconectionAfter reaching max_attemps an exeption will be thrown and on_disconnect event will be
fired.hub_connection=HubConnectionBuilder()\.with_url(server_url)\....build()Configuring aditional headershub_connection=HubConnectionBuilder()\.with_url(server_url,options={"headers":{"mycustomheader":"mycustomheadervalue"}})....build()Configuring aditional querystring parametersserver_url="http.... /?myquerystringparam=134&foo=bar"connection=HubConnectionBuilder()\.with_url(server_url,options={})\.build()Congfigure skip negotiationhub_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 secconds of ping messagehub_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 logginghub_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 messagepackfromsignalrcore.protocol.messagepack_protocolimportMessagePackHubProtocolHubConnectionBuilder()\.with_url(self.server_url,options={"verify_ssl":False})\....with_hub_protocol(MessagePackHubProtocol())\....build()EventsOn connect / On disconnecton_open - fires when connection is openned and ready to send messages
on_close - fires when connection is closedhub_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 operationReceiveMessage - signalr method
print - function that has as parameters args of signalr methodhub_connection.on("ReceiveMessage",print)Sending messagesSendMessage - signalr method
username, message - parameters of signalrmethodhub_connection.send("SendMessage",[username,message])Sending messages with callbackSendMessage - signalr method
username, message - parameters of signalrmethodsend_callback_received=threading.Lock()send_callback_received.acquire()self.connection.send("SendMessage",# Method[self.username,self.message],# Paramslambdam:send_callback_received.release())# Callbackifnotsend_callback_received.acquire(timeout=1):raiseValueError("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 Streamingfromsignalrcore.subjectimportSubjectsubject=Subject()# Start Streaminghub_connection.send("UploadStream",subject)# Each iterationsubject.next(str(iteration))# End streamingsubject.complete()Full ExamplesExamples will be avaiablehereIt were developed using package fromaspnet core - SignalRChatChat exampleA mini example could be something like this:importloggingimportsysfromsignalrcore.hub_connection_builderimportHubConnectionBuilderdefinput_with_default(input_text,default_value):value=input(input_text.format(default_value))returndefault_valueifvalueisNoneorvalue.strip()==""elsevalueserver_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 loginwhilemessage!="exit()":message=input(">> ")ifmessageisnotNoneandmessage!=""andmessage!="exit()":hub_connection.send("SendMessage",[username,message])hub_connection.stop()sys.exit(0)