Обработка ошибок подключения к QUIK
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
__pycache__
|
||||
55
QuikPy.py
55
QuikPy.py
@@ -37,10 +37,14 @@ class QuikPy(metaclass=Singleton): # Singleton класс
|
||||
fragments = [] # Будем получать ответ в виде списка фрагментов. Они могут быть разной длины. Ответ может состоять из нескольких фрагментов
|
||||
while getattr(currentThread, 'process', True): # Пока поток нужен
|
||||
while True: # Пока есть что-то в буфере ответов
|
||||
fragment = socketCallbacks.recv(self.bufferSize) # Читаем фрагмент из буфера
|
||||
fragments.append(fragment.decode('cp1251')) # Переводим фрагмент в Windows кодировку 1251, добавляем в список
|
||||
if len(fragment) < self.bufferSize: # Если в принятом фрагменте данных меньше чем размер буфера
|
||||
break # то, возможно, это был последний фрагмент, выходим из чтения буфера
|
||||
try:
|
||||
fragment = socketCallbacks.recv(self.bufferSize) # Читаем фрагмент из буфера
|
||||
except ConnectionResetError:
|
||||
print("Соединение сброшено")
|
||||
else:
|
||||
fragments.append(fragment.decode('cp1251')) # Переводим фрагмент в Windows кодировку 1251, добавляем в список
|
||||
if len(fragment) < self.bufferSize: # Если в принятом фрагменте данных меньше чем размер буфера
|
||||
break # то, возможно, это был последний фрагмент, выходим из чтения буфера
|
||||
data = ''.join(fragments) # Собираем список фрагментов в строку
|
||||
dataList = data.split('\n') # Одновременно могут прийти несколько функций обратного вызова, разбираем их по одной
|
||||
fragments = [] # Сбрасываем фрагменты. Если последнюю строку не сможем разобрать, то занесем ее сюда
|
||||
@@ -111,10 +115,32 @@ class QuikPy(metaclass=Singleton): # Singleton класс
|
||||
def ProcessRequest(self, Request):
|
||||
"""Отправляем запрос в QUIK, получаем ответ из QUIK"""
|
||||
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 = [] # Гораздо быстрее получать ответ в виде списка фрагментов
|
||||
|
||||
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, добавляем в список
|
||||
if len(fragment) < self.bufferSize: # Если в принятом фрагменте данных меньше чем размер буфера
|
||||
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. Функции обратного вызова
|
||||
self.OnFirm = self.DefaultHandler # 1. Новая фирма
|
||||
@@ -162,10 +188,18 @@ class QuikPy(metaclass=Singleton): # Singleton класс
|
||||
self.RequestsPort = RequestsPort # Порт для отправки запросов и получения ответов
|
||||
self.CallbacksPort = CallbacksPort # Порт для функций обратного вызова
|
||||
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):
|
||||
"""Вход в класс, например, с with"""
|
||||
@@ -590,3 +624,4 @@ class QuikPy(metaclass=Singleton): # Singleton класс
|
||||
|
||||
def __del__(self):
|
||||
self.CloseConnectionAndThread() # Закрываем соединение для запросов и поток обработки функций обратного вызова
|
||||
|
||||
|
||||
Reference in New Issue
Block a user