socket.io client always closing - python

hey i tried making this connection work... i first installed the updated version of python-socketio[client]==5.7.1 but apparently this version supports EIO=4 and the socket.io client i'm trying to open is EIO=3.. so i had to uninstall it and install an old version python-socketio==4.6.1 . after that i tried running this code
import socketio
sio = socketio.Client(ssl_verify=False,logger=True,engineio_logger=True)
#sio.event
def connect():
print("Connected!")
sio.emit("authorization",{"session":"2ot3i7..................3h","isDemo":1})
#sio.event
def connect_error(data):
print("The connection failed!\n\n" + data)
#sio.event
def disconnect():
print("Disconnected!")
#sio.on('*')
def catch_all(event,data):
pass
#sio.on('handshake')
def on_message(data):
print('Handshake',data)
sio.emit("instruments/update",{"asset":"GBPUSD","period":60})
sio.emit("indicator/list")
sio.emit("drawing/load")
sio.emit("pending/list")
sio.emit("chart_notification/get")
sio.emit("depth/follow","GBPUSD")
sio.emit("tick")
sio.emit("settings/store",{"chartId":"graph","settings":{"chartId":"graph","chartType":2,"currentExpirationTime":0,"isFastOption":False,"isFastAmountOption":False,"isIndicatorsMinimized":False,"isIndicatorsShowing":True,"isShortBetElement":False,"chartPeriod":4,"currentAsset":{"symbol":"GBPUSD"},"dealValue":1000,"dealPercentValue":1,"isVisible":True,"timePeriod":60,"gridOpacity":8,"isAutoScrolling":1,"isOneClickTrade":True,"upColor":"#0FAF59","downColor":"#FF6251"}})
if __name__ == '__main__' :
sio.connect('https://ws.quotex.io/socket.io/', transports=['websocket'])
sio.wait()
and here is what came back...
Attempting WebSocket connection to wss://ws.quotex.io/socket.io/?transport=websocket&EIO=3
WebSocket connection accepted with {'sid': '5AeKOf4oS0U-pHnaB1-2', 'upgrades': [], 'pingInterval': 25000, 'pingTimeout': 5000}
Engine.IO connection established
Sending packet PING data None
Received packet MESSAGE data 0
Received packet MESSAGE data 1
Namespace / is connected
Connected!
Emitting event "authorization" [/]
Sending packet MESSAGE data 2["authorization",{"session":"2ot......................3h","isDemo":1}]
Disconnected!
Received packet NOOP data None
WebSocket connection was closed, aborting
Waiting for write loop task to end
Exiting write loop task
Waiting for ping loop task to end
PONG response has not been received, aborting
Exiting ping task
Engine.IO connection dropped
Connection failed, new attempt in 1.41 seconds
Exiting read loop task
Attempting WebSocket connection to wss://ws.quotex.io/socket.io/?transport=websocket&EIO=3
WebSocket connection accepted with {'sid': 'sQvjGss3KsxnBzQ2B2gI', 'upgrades': [], 'pingInterval': 25000, 'pingTimeout': 5000}
Engine.IO connection established
Sending packet PING data None
Reconnection successful
Received packet MESSAGE data 0
Namespace / is connected
Received packet MESSAGE data 1
Connected!
Emitting event "authorization" [/]
Received packet NOOP data None
Sending packet MESSAGE data 2["authorization",{"session":"2ot.......................3h","isDemo":1}]
WebSocket connection was closed, aborting
Waiting for write loop task to end
Exiting write loop task
Waiting for ping loop task to end
PONG response has not been received, aborting
Exiting ping task
Engine.IO connection dropped
Disconnected!
Disconnected!
Connection failed, new attempt in 0.90 seconds
Exiting read loop task
i had to kill the terminal cause it was trying to reconnect
please if you have any questions to make my explanations clear you can comment and i'll answer
thank you if you can give an advice

Related

How to send messages from Flask server to RabbitMQ server queue?

I'm trying to send a message from Flask server, which acts as a producer, to a RabbitMQ server queue. The port I'm using to produce the messages is '5672'.
I've created an exchange and a queue on RabbitMQ's Management server and the main goal is to receive a message in the server's queue.
This is the code that I have at the moment, it does not produce any errors and returns that the message has been sent:
#app.route("/create/<message>")
def create_bucket(message):
credentials = pika.PlainCredentials("guest", "guest")
connection = pika.BlockingConnection(pika.ConnectionParameters(host="localhost", credentials=credentials))
channel = connection.channel()
channel.queue_declare(queue="TestQueue", durable=True)
channel.basic_publish(exchange="TestExchange", routing_key="TestQueue", body=message, properties=pika.BasicProperties(delivery_mode=2))
connection.close()
return "[x] Message sent %s" % message
if __name__ == "__main__":
app.run(debug=True, port=5672)
Though the message does not appear in RabbitMQ's server's queue.
Are there any resources or ways to send a message from Flask's server to RabbitMQ's server queue?
Managed to solve the problem by deleting routing_key="TestQueue", as the routing_key was not declared in RabbitMQ server.

How to keep connectivity status between node.js and python?

I have web application based on Node.js and python based hardware. I want to keep status of connectivity between web server and hardware. If Hardware gets disconnected from web application then web application should get event or notification so based on that i can send notification to user. I have used mqtt for data communication, but to keep connection status I can't use MQTT coz it is connected with broker. I don't want to increase more load on server.
Which tools/technology/protocol/method should i use to keep connection status that device is offline or online?. That I also want use when user tries to send data to hardware using web application and if device is not connected with server then user should get notification that device is offline based on connection status.
The following code demonstrates the process I was hinting at in the comments.
The LWT feature tells the broker to publish a message marking the client as offline when it fails to respond in 1.5 times the keepalive period. If the client cleanly disconnects then it needs to mark it's self as offline. The client marks it's self as online when it connects to the broker.
All the status messages have the retained bit set so they will always be delivered when a client subscribes to the status topic.
import paho.mqtt.client as mqtt
# The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, rc):
print("Connected with result code "+str(rc))
# Subscribing in on_connect() means that if we lose the connection and
# reconnect then subscriptions will be renewed.
client.subscribe("some/application/topic")
# set status message to online
client.publish("status/client1", payload="online", retain=True)
# The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg):
print(msg.topic+" "+str(msg.payload))
if str(msg.payload) == "shutdown":
# update status to offline as this will be a clean dissconect
client.publish("status/client1", payload="offline", retain=True)
client.disconnect()
client = mqtt.Client(client_id="client1")
client.on_connect = on_connect
client.on_message = on_message
client.will_set("status/client1", payload="offline", retain=True)
client.connect("mqtt.eclipse.org", 1883, 60)
# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
# Other loop*() functions are available that give a threaded interface and a
# manual interface.
client.loop_forever()
It will be up to the OP to implement the notification about sending messages to offline clients requested at the end of the question.

Allow RabbitMQ and Pika maintain the conection always open

I've a Python script which reads stuff from a stream, and when a new string gets readed, it pushes its content (a string) to a RabbitMQ queue.
The thing is that the stream might not send messages in 1, 2 or 9h or so, so I would like to have the RabbitMQ connection always open.
The problem is that when I create the conection and the channel:
self.connection = pika.BlockingConnection(pika.ConnectionParameters(host=self.host, credentials=self.credentials))
channel = self.connection.channel()
channel.exchange_declare(exchange=self.exchange_name, exchange_type='fanout')
... and if after an hour a message arrives, I get this error:
File "/usr/local/lib/python3.7/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
File "/var/opt/rabbitmq-agent.py", line 34, in push_to_queue
raise Exception("Error sending the message to the queue: " + format(e))
Exception: Error sending the message to the queue: Send message to publisher error: Channel allocation requires an open connection: <SelectConnection CLOSED socket=None params=<ConnectionParameters host=x port=xvirtual_host=/ ssl=False>>
Which I suppose is that the connection has been closed between the rabbitmq server and client.
How can I avoid this? I would like to have a "please, keep the connection alive always". Maybe setting a super-big heartbeat in the connection parameters of Pika? Something like this:
self.connection = pika.BlockingConnection(pika.ConnectionParameters(host=self.host, credentials=self.credentials, heartbeat=6000))
Any other cooler solutions would be highly appreciated.
Thanks in advance
I would suggest you check connection every time before sending message and if the connection is closed then simply reconnect.
if not self.connection or self.connection.is_closed:
self.connection = pika.BlockingConnection(pika.ConnectionParameters(host=self.host, credentials=self.credentials))
channel = self.connection.channel()
channel.exchange_declare(exchange=self.exchange_name, exchange_type='fanout')
You could try adding heartbeat to your ConnectionParameters. This will create light traffic by sending heartbeats every specified seconds. This will exercise the connections. Some firewalls or proxies tend to scrape idle connections. Even RabbitMQ has a timeout on connections that are idle.
import pika
# Set the connection parameters to connect to rabbit-server1 on port 5672
# on the / virtual host using the username "guest" and password "guest"
credentials = pika.PlainCredentials('guest', 'guest')
parameters = pika.ConnectionParameters('rabbit-server1',
5672,
'/',
heartbeat=60,
credentials)
See here for pika documentation.
Additionally you should have code in place that mitigates network disconnection. This can always happen and will. So appart from the heartbeat have some exception handling ready to re-open closed connections in a graceful way.

Python Sockets: How to detect when client has disconnected ungracefully? (e.g. WiFi disconnect)

I'm writing a pair of client/server scripts where it is important to maintain connection as well as detect quickly when the client disconnects. The server normally only sends data, so to test if the client has disconnected normally, I set the socket to timeout mode and check what it returns:
try: # check if client disconnect
c.settimeout(1)
if not (c.recv(1024)):
print("## Socket disconnected! ##")
c.settimeout(None)
closeConnection(c)
return
except Exception as e:
print(e)
c.settimeout(None)
This works instantly if I close the client. However, if I disconnect the WiFi on the client machine, the recv on the server doesn't return anything. It just times out like it would if the connection was up but there wasn't anything being sent.
I've tried using send() to send empty messages to the client as a way to poll. When I do this, the operation succeeds and returns 0 regardless of if the client has disconnected.

Detect when Websocket is disconnected, with Python Bottle / gevent-websocket

I'm using the gevent-websocket module with Bottle Python framework.
When a client closes the browser, this code
$(window).on('beforeunload', function() { ws.close(); });
helps to close the websocket connection properly.
But if the client's network connection is interrupted, no "close" information can be sent to the server.
Then, often, even 1 minute later, the server still believes the client is connected, and the websocket is still open on the server.
Question: How to detect properly that a websocket is closed because the client is disconnected from network?
Is there a websocket KeepAlive feature available in Python/Bottle/gevent-websocket?
One answer from Web Socket: cannot detect client connection on internet disconnect suggests to use a heartbeat/ping packet every x seconds to tell the server "I'm still alive". The other answer suggests using a setKeepAlive(true). feature. Would this feature be available in gevent-websocket?
Example server code, taken from here:
from bottle import get, template, run
from bottle.ext.websocket import GeventWebSocketServer
from bottle.ext.websocket import websocket
users = set()
#get('/')
def index():
return template('index')
#get('/websocket', apply=[websocket])
def chat(ws):
users.add(ws)
while True:
msg = ws.receive()
if msg is not None:
for u in users:
u.send(msg)
else:
break
users.remove(ws)
run(host='127.0.0.1', port=8080, server=GeventWebSocketServer)
First you need to add a timeout to the receive() method.
with gevent.Timeout(1.0, False):
msg = ws.receive()
Then the loop will not block, if you send even an empty packet and the client doesn't respond, WebsocketError will be thrown and you can close the socket.

Categories