108 lines
3.2 KiB
Python
108 lines
3.2 KiB
Python
#
|
|
# Library with socket client for use by consumers
|
|
#
|
|
import atexit, os, sys
|
|
import struct, json
|
|
import socket
|
|
|
|
|
|
is_registered = False
|
|
def handle_registration(socket_path, client_name, debug=0):
|
|
global is_registered
|
|
data = dict()
|
|
|
|
if is_registered:
|
|
message = {'command': 'DEREGISTER', 'client': client_name}
|
|
else:
|
|
# fork server if it's not already running
|
|
message = {'command': 'REGISTER', 'client': client_name}
|
|
|
|
try:
|
|
data = socket_comms(socket_path, message, debug)
|
|
if data['status'] == 'REGISTERED':
|
|
is_registered = True
|
|
elif data['status'] == 'DEREGISTERED':
|
|
is_registered = False
|
|
else:
|
|
raise OSError("{} registration: invalid response: {}".format(client_name, data))
|
|
|
|
except Exception as e:
|
|
if is_registered:
|
|
print("{}: failed to register with daemon: {}".format(client_name, e))
|
|
else:
|
|
print("{}: failed to deregister with daemon: {}".format(client_name, e))
|
|
|
|
return data
|
|
|
|
|
|
def socket_comms(socket_path, request_data, debug=0):
|
|
response_data = dict()
|
|
|
|
# Create a UDS socket
|
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
|
|
|
# Connect the socket to the port where the server is listening
|
|
if debug > 2:
|
|
print('socket client: connecting to {}'.format(socket_path))
|
|
try:
|
|
sock.connect(socket_path)
|
|
except socket.error as msg:
|
|
if msg.errno == 2:
|
|
print("Failed to connect to bmspy daemon")
|
|
else:
|
|
print("socket client: {}".format(msg))
|
|
|
|
# Send request
|
|
if debug > 2:
|
|
print('socket client: sending {!r}'.format(request_data))
|
|
request = bytes()
|
|
try:
|
|
request = json.dumps(request_data).encode()
|
|
# add length to the start of the json string, so we know how much to read on the other end
|
|
length = struct.pack('!I', len(request))
|
|
if debug > 3:
|
|
print("socket client: outgoing request length: {}, encoded as {}".format(len(request), length))
|
|
request = length + request
|
|
if debug > 4:
|
|
print("socket client: outgoing request: {}".format(request))
|
|
except:
|
|
print("socket client ERROR: unable to encode request")
|
|
sys.exit(1)
|
|
sock.sendall(request)
|
|
|
|
# get length of expected json string
|
|
response = sock.recv(struct.calcsize('!I'))
|
|
try:
|
|
length = struct.unpack('!I', response)[0]
|
|
if debug > 4:
|
|
print("socket client: incoming length: {}, encoded as {}".format(length, response))
|
|
# read length bytes
|
|
response = sock.recv(length)
|
|
if debug > 3:
|
|
print("socket client: incoming response: {}".format(response))
|
|
response_data = json.loads(response)
|
|
except:
|
|
print("socket client ERROR: unable to decode response")
|
|
sys.exit(1)
|
|
if debug > 2:
|
|
print('socket client: received {!r}'.format(response_data))
|
|
|
|
sock.close()
|
|
|
|
return response_data
|
|
|
|
|
|
def read_data(socket_path, client_name, debug=0):
|
|
data = dict()
|
|
|
|
data = socket_comms(socket_path, {'command': 'GET', 'client': client_name}, debug)
|
|
|
|
if data is None:
|
|
raise
|
|
|
|
return data
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(0)
|