-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwebsocket_client.py
86 lines (73 loc) · 2.63 KB
/
websocket_client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from ws4py.client.threadedclient import WebSocketClient
from ws4py.messaging import PingControlMessage
import threading
import time
import socket
class Client(WebSocketClient):
lock = threading.Lock()
def __init__(self, url):
super().__init__(url)
self.message_broker = None
self.ping_attempts = 0
def setup(self, message_broker, timeout=15):
try:
self.__init__(self.url)
self.message_broker = message_broker
self.connect()
self.run_forever()
except KeyboardInterrupt:
self.close()
except:
# print("Timing out for %i seconds. . ." % timeout)
time.sleep(timeout)
# print("Attempting reconnect. . .")
self.setup(self.message_broker)
def closed(self, code, reason=None):
print("Websocket Client Connection Lost: ", code, reason)
self.message_broker.pi_clients.remove(self)
# Update frontend with loss of connectivity
self.message_broker.check_and_update_ws_client()
time.sleep(3)
try:
self.sock.close()
except AttributeError:
# socket already closed
pass
self.setup(self.message_broker)
def opened(self):
pingthread = PingThread(self, frequency=30)
pingthread.start()
print("Connected to WebSocket")
self.message_broker.pi_clients.append(self)
# update front with connectivity
self.message_broker.check_and_update_ws_client()
def received_message(self, m):
# Check message broker for any objects that match the message
self.message_broker.check_units(m)
def ponged(self, pong):
# Reset the ping attempts
Client.lock.acquire()
self.ping_attempts = 0
Client.lock.release()
class PingThread(threading.Thread):
def __init__(self, websocket, frequency=2.0):
threading.Thread.__init__(self)
self.websocket = websocket
self.frequency = frequency
self.go = False
def run(self):
self.go = True
while self.go:
time.sleep(self.frequency)
if self.websocket.terminated:
break
try:
self.websocket.send(PingControlMessage(data='beep'))
# Track the number of ping attempts
Client.lock.acquire()
self.websocket.ping_attempts += 1
Client.lock.release()
except (socket.error,RuntimeError):
self.websocket.server_terminated = True
self.websocket.close_connection()
break