Обработка ошибок подключения к QUIK

This commit is contained in:
denis
2023-02-05 18:49:42 +00:00
parent 4835c35906
commit d31495c989
2 changed files with 50 additions and 14 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
__pycache__

View File

@@ -37,10 +37,14 @@ class QuikPy(metaclass=Singleton): # Singleton класс
fragments = [] # Будем получать ответ в виде списка фрагментов. Они могут быть разной длины. Ответ может состоять из нескольких фрагментов fragments = [] # Будем получать ответ в виде списка фрагментов. Они могут быть разной длины. Ответ может состоять из нескольких фрагментов
while getattr(currentThread, 'process', True): # Пока поток нужен while getattr(currentThread, 'process', True): # Пока поток нужен
while True: # Пока есть что-то в буфере ответов while True: # Пока есть что-то в буфере ответов
fragment = socketCallbacks.recv(self.bufferSize) # Читаем фрагмент из буфера try:
fragments.append(fragment.decode('cp1251')) # Переводим фрагмент в Windows кодировку 1251, добавляем в список fragment = socketCallbacks.recv(self.bufferSize) # Читаем фрагмент из буфера
if len(fragment) < self.bufferSize: # Если в принятом фрагменте данных меньше чем размер буфера except ConnectionResetError:
break # то, возможно, это был последний фрагмент, выходим из чтения буфера print("Соединение сброшено")
else:
fragments.append(fragment.decode('cp1251')) # Переводим фрагмент в Windows кодировку 1251, добавляем в список
if len(fragment) < self.bufferSize: # Если в принятом фрагменте данных меньше чем размер буфера
break # то, возможно, это был последний фрагмент, выходим из чтения буфера
data = ''.join(fragments) # Собираем список фрагментов в строку data = ''.join(fragments) # Собираем список фрагментов в строку
dataList = data.split('\n') # Одновременно могут прийти несколько функций обратного вызова, разбираем их по одной dataList = data.split('\n') # Одновременно могут прийти несколько функций обратного вызова, разбираем их по одной
fragments = [] # Сбрасываем фрагменты. Если последнюю строку не сможем разобрать, то занесем ее сюда fragments = [] # Сбрасываем фрагменты. Если последнюю строку не сможем разобрать, то занесем ее сюда
@@ -111,10 +115,32 @@ class QuikPy(metaclass=Singleton): # Singleton класс
def ProcessRequest(self, Request): def ProcessRequest(self, Request):
"""Отправляем запрос в QUIK, получаем ответ из QUIK""" """Отправляем запрос в QUIK, получаем ответ из QUIK"""
rawData = json.dumps(Request) # Переводим запрос в формат JSON rawData = json.dumps(Request) # Переводим запрос в формат JSON
self.socketRequests.sendall(f'{rawData}\r\n'.encode()) # Отправляем запрос в QUIK # self.socketRequests.settimeout(1)
# print(self.socketRequests.timeout)
# self.socketRequests.sendall(f'{rawData}\r\n'.encode()) # Отправляем запрос в QUIK
try:
self.socketRequests.sendall(f'{rawData}\r\n'.encode()) # Отправляем запрос в QUIK
except Exception:
# raise TimeoutError("Истёк таймаут подключения к QUIK")
print("Истёк таймаут подключения к QUIK")
data = {"data": "error"}
return data
fragments = [] # Гораздо быстрее получать ответ в виде списка фрагментов fragments = [] # Гораздо быстрее получать ответ в виде списка фрагментов
while True: # Пока фрагменты есть в буфере while True: # Пока фрагменты есть в буфере
fragment = self.socketRequests.recv(self.bufferSize) # Читаем фрагмент из буфера # print(fragments)
try:
fragment = self.socketRequests.recv(self.bufferSize) # Читаем фрагмент из буфера
assert len(fragment) > 0
except (TimeoutError, AssertionError):
print("Истёк таймаут подключения к QUIK")
data = {"data": "error"}
return data
except ConnectionResetError:
print("Соединение сброшено")
data = {"data": "error"}
return data
fragments.append(fragment.decode('cp1251')) # Переводим фрагмент в Windows кодировку 1251, добавляем в список fragments.append(fragment.decode('cp1251')) # Переводим фрагмент в Windows кодировку 1251, добавляем в список
if len(fragment) < self.bufferSize: # Если в принятом фрагменте данных меньше чем размер буфера if len(fragment) < self.bufferSize: # Если в принятом фрагменте данных меньше чем размер буфера
data = ''.join(fragments) # Собираем список фрагментов в строку data = ''.join(fragments) # Собираем список фрагментов в строку
@@ -125,7 +151,7 @@ class QuikPy(metaclass=Singleton): # Singleton класс
# Инициализация и вход # Инициализация и вход
def __init__(self, Host='127.0.0.1', RequestsPort=34130, CallbacksPort=34131): def __init__(self, Host='127.0.0.1', RequestsPort=34130, CallbacksPort=34131, connection_timeout=None):
"""Инициализация""" """Инициализация"""
# 2.2. Функции обратного вызова # 2.2. Функции обратного вызова
self.OnFirm = self.DefaultHandler # 1. Новая фирма self.OnFirm = self.DefaultHandler # 1. Новая фирма
@@ -162,10 +188,18 @@ class QuikPy(metaclass=Singleton): # Singleton класс
self.RequestsPort = RequestsPort # Порт для отправки запросов и получения ответов self.RequestsPort = RequestsPort # Порт для отправки запросов и получения ответов
self.CallbacksPort = CallbacksPort # Порт для функций обратного вызова self.CallbacksPort = CallbacksPort # Порт для функций обратного вызова
self.socketRequests = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Создаем соединение для запросов self.socketRequests = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Создаем соединение для запросов
self.socketRequests.connect((self.Host, self.RequestsPort)) # Открываем соединение для запросов if connection_timeout is not None:
self.socketRequests.settimeout(connection_timeout)
self.callbackThread = threading.Thread(target=self.CallbackHandler,
name='CallbackThread') # Создаем поток обработки функций обратного вызова
try:
self.socketRequests.connect((self.Host, self.RequestsPort)) # Открываем соединение для запросов
except TimeoutError:
raise ConnectionError("Истёк таймаут подключения к QUIK")
else:
self.callbackThread.start() # Запускаем поток
self.callbackThread = threading.Thread(target=self.CallbackHandler, name='CallbackThread') # Создаем поток обработки функций обратного вызова
self.callbackThread.start() # Запускаем поток
def __enter__(self): def __enter__(self):
"""Вход в класс, например, с with""" """Вход в класс, например, с with"""
@@ -590,3 +624,4 @@ class QuikPy(metaclass=Singleton): # Singleton класс
def __del__(self): def __del__(self):
self.CloseConnectionAndThread() # Закрываем соединение для запросов и поток обработки функций обратного вызова self.CloseConnectionAndThread() # Закрываем соединение для запросов и поток обработки функций обратного вызова