LINUX.ORG.RU

Вопрос по сокет ответу

 , ,


0

2

Есть 2 функции, 1 в бесконечном цикле проверяет ответ сокета, вторую можно вызвать когда угодно и она так же возвращает ответ сокета, собственно вопрос возникает логичный, если 1 функция постоянно проверяет начиние нужного ответа, то при выполнении 2й ответа никакого не будет, 1я его уже словила.
Ведь даже есть сделать проверку if self.socket.recv() == 'I' это уже будет считаться за получение ответа.

★★★

Ответ на: комментарий от AntonI

да это логично, но представь ситуацию у тебя крутиться в потоке цикл, в котором к примеру ловяться сообщения почтовые по сокету, а при выполнении другой функции (например после нажатия кнопки) генериться новый адрес так же ожидающий ответа сокета, так вот мы если в цикле даже словим этот ответ, как его заставить отдать это все в нужную ф-ю?

foozzi ★★★ ()
Ответ на: комментарий от t184256

Я просто не увидел вопроса в исходном посте. Мол, парень, ты всё верно рассуждаешь, но если такой возможности какую ты хочешь нет, то как нужно переделать программу, чтобы получить то что ты хочешь?

Если он не может решить такую задачу, то в программировании ему делать нечего.

eternal_sorrow ★★★★★ ()
Ответ на: комментарий от foozzi

Яннп. Я сам с окетами возился очень давно поэтому могу путать.

Есть цикл который слушает порт, пришел запрос - он создал сокет, повесил на сокет в отдельном треде обрабатывающую функцию и слушает порт дальше.

В чем проблемы?

AntonI ★★ ()

вторую можно вызвать когда угодно и она так же возвращает ответ сокета

а если ответа нет, то что она вернёт?

ты читай в своём треде с бесконечным циклом из сокета в какой-то глобальный буфер, а в остальных тредах читай не из сокета, а из того буфера.

anonymous ()
Ответ на: комментарий от anonymous

Но если мне нужно отправить пакет и получить ответ, мне ведь нужно отправить определенный пакет из определенной функции для удобства и далее работать с ответом

foozzi ★★★ ()
Ответ на: комментарий от foozzi

пришел запрос - он создал сокет, повесил на сокет в отдельном треде обрабатывающую функцию

Советы заслуженного собаковода(с). Я так поняла, дядя на каждый коннект предлагает отдельный поток запустить. Учитывая питон, это будет еще то тормозилово.

anonymous ()
Ответ на: комментарий от anonymous

Учитывая питон, это будет еще то тормозилово.

все зависит от кол-ва клиентов и объема данных, у меня на питоне микросервис крутится, который собирает данные с 7 датчиков раз в минуту и шлет их в заббикс,причем сокеты в блокированном режиме и все работает уже год как по маслу.

jo_b1ack ★★★★ ()
Ответ на: комментарий от foozzi

Вариант 1) главный поток будет будить потоки обработчики, которые будут обрабатывать данные Вариант 2) потоки будут читать без опустошения очереди Вариант 3) поток читает и если данные ему не подходят будит другой поток, который обработает как надо, в тоже время основной поток засыпает

AKonia ()
Ответ на: комментарий от eternal_sorrow

вообще суть вот в чем, используя websocket-client либу:

class Dropmail:
	def __init__(self, server='wss://dropmail.me/websocket'):
		self.emails = dict()
		self.default_email = None
		self._supported_domains = None

		self.socket = websocket.create_connection(server)
так вот если подрубиться к нему (self.socket.recv()) тут же получим адрес почты (в моем конкретно случае) и соответственно если постоянно дергать while True это:
	def next_message(self):
		# Message contains an 'I' character followed by
		# a json-encoded message
		raw_message = self.socket.recv()[1:]
		message = json.loads(raw_message)
		return message
мы будем тягать все ответы что логично и основной вопрос это как мне слать пакет к примеру на получение или восстановления почты (опять же на конкретном примере) и получать его в ответе например ф-ции get_new_mail, вся проблема в зацикленном next_message, то есть я вечно чекаю на наличие новых сообщений и при попытке создать новый ящик вся логика пойдет к черту.
Хоть убейте не могу понять как это без костылей и говнокода решить

код get_new_mail:
	def get_new_mail(self, domain=None):
		if domain in self.supported_domains:
			packet = 'A{}'.format(domain)
		elif not domain:
			packet = 'M'
		else:
			raise ValueError('Requested address from domain "{}", but not in list of supported domains\n({})'.format(domain, self.supported_domains))

		self.socket.send(packet)
		account_info = self.socket.recv()

foozzi ★★★ ()
Последнее исправление: foozzi (всего исправлений: 1)
Ответ на: комментарий от foozzi

после нажатия кнопки) генериться новый адрес так же ожидающий ответа сокета

Какой новый адрес? Что это? Помимо этого ты вообще понимаешь, что сокет это просто поток данных (если речь о SOCK_STREAM), и что тебе так или иначе придётся из него все вычитывать, т.к. если тебе что-то не понравилось, то это нельзя просто положить обратно, чтобы оно потом само как-то еще раз пришло? Объясни простыми словами, что ты пытаешься сделать, без деталей реализации.

Пока что из всего ясно лишь то, что тебе надо вычитывать ВСЕ поступающие данные (полл/селектом или еще чем, чтобы не висеть и не жечь железо), там же по месту резать их в какой-то массив на логические пакеты, буферизуя неполные остатки (пакет может придти не весь за раз, зависит от того, кто и что тебе шлет), и потом «по кнопке» искать в этом массиве ближайший пакет нужного типа, вынимать его и обрабатывать. Хотя непонятно, зачем вообще нужна кнопка, если пакет и так уже пришел.

А если обе стороны свои, лучше заюзай какой-нибудь готовый json-rpc модуль или подобный ему, встраиваемый в ивентлуп и стреляющий готовыми событиями, иначе будешь ковыряться с этим еще пару месяцев. Без лишнего негатива, но у тебя в голове полная каша, а область технически непростая, и пока ее не разберешь, ничего не выйдет.

anonymous ()
Ответ на: комментарий от foozzi

как мне слать пакет к примеру на получение или восстановления почты (опять же на конкретном примере) и получать его в ответе

В одной последовательности операций, в одной функции такое не сделать. Чтобы понимать в цикле чтения, какая операция сейчас «продолжается», можно нумеровать пакеты. То есть отправка запроса на восстановление выглядит как req_id = new_id(); socket.send({..., req_id:req_id}); delayed_tasks.push([req_id, self.continue_here]). Позже, когда сервер пришлет ответ, в нем он укажет, на какой req_id он ответил. Код в цикле чтения увидит что есть req_id, найдет продолжение в delayed_tasks[] и вызовет task[1](packet), т.е. твой self.coninue_here(packet). Это лишь пример, лучше возьми прям json-rpc либу готовую и на ней уже либо развесь все обработчики, либо асинк-авайт стиль заюзаешь, если он в ней есть. Названий не могу подсказать, не питонист.

anonymous ()