LINUX.ORG.RU

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

 ,


0

2

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

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

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

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

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

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

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

окей и все же, какое нибудь банальное решение есть? Конечно я могу это все накостылить, но это уже будет сложно кодом назвать.

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

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

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

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

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

Ну да, кто то слушает сокет и набивает очередь тем что оттуда пришло, остальные эту очередь разбирают как то, выбирают то что им надо.

AntonI ★★★★
()

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

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

anonymous
()

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

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

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

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

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

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

Спасибо, буду смотреть в сторону проверки готовности сокета с определенным флагом

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

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

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

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

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

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

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

А меня учили «кривой дизайн, это всегда кривой дизайн. И тебе должно быть стыдно, что пишешь такую фигню.»

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

Вариант 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()

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

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

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

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

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

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

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

В одной последовательности операций, в одной функции такое не сделать. Чтобы понимать в цикле чтения, какая операция сейчас «продолжается», можно нумеровать пакеты. То есть отправка запроса на восстановление выглядит как 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
()
Ответ на: комментарий от eternal_sorrow

Тогда пиши «что спросить-то хотел». а то не вышло у тебя докопаться.

t184256 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.