LINUX.ORG.RU

C,TCP-Server

 , ,


0

1

Добрый вечер, есть TCP сервер на си с libevent, к нему переодически подключаются некоторые девайсы (у каждого девайса свой идентификатор), сервак разбирает сообщения от девайсов и отдельном процессе шлет данные в стороний сервис (вида: ИДЕНТИФИКАТОР+еще какие-то данные). этот сервис в свою очередь передают информацию по вэб сокетам клиенту в браузер, дальше клиент видит, что некий девайс в данный момент «в сети» и может отправить ему какое-нибудь сообщение, это сообщение так же через вэб сокеты передается второму сервису, который в свою очередь передает данные сишному серверу (вида ИДЕНТИФИКАТОР+текст сообщения). Вопрос, как заставить тсп сервер сразу отправить это сообщение девайсу? Как вариант входящие сообщения от второго сервиса складывать в очередь и при новом сообщении от девайса проверять в этой очереди наличие сообщения. но такой способ будет работать с задержкой, т.к новое сообщение от девайса может придти через 5,10 минут. Второй вариант: сделать третий процесс (1-ый процесс это сам приемник сообщений от девайсов, 2-ой передача сторонему сервису инфу о новых подключениях/отключениях) и в нем в бесконечном цикле перебирать наличие в очереди сообщений для девайсов и если есть сообщение, то перебирать уже очередь «активных» девайсов и при совпадении отправлять сообщение...но это цикл в цикле и если активных девайсов и сообщений будет много, то как мне кажется будет не совсем правильно... Кто-нибудь реализовывал подобные вещи, что можете посоветовать? Заранее Спасибо.


Вот это мне не совсем понятно:

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

Почему, если tcp-сервер на Си, если он получил сообщение, не может его сразу передать устройству, а должен ждать, пока придёт сообщение от устройства? Он, что, получает сообщение для устройсва не через libevent?

Сервер, который слушает, пусть сам и организует очередь. При получении сообщения смотрит, если устройсво подключено, отправляет сообщение сразу, если не подключено, складывает в очередь. При подключении устройсва проходит по очереди и смотрит, есть ли для него сообщения.

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

Ну вот и я так думал сначала, что-то подобное:

<цикл перебора очереди сообщений> 
    <цикл перебора активных девайсов>
        <если идентификатор девайса совпадает с идентификатором получателя сообщения>
            <отправка сообщения>

И вынести этот цикл тогда в отдельный процесс, т.к сообщение может придти в любой момент. Но на сколько такой вариант будет накладным? Каждый раз так перебирать 2 очереди. И могут ли возникнуть проблемы, если вдруг одновременно придет сообщение от этого девайса и другой потом в этом цикле начнет отправлять сообщение этому же девайсу?

hound
() автор топика

На go, который был создан ровно для таких задач, всё, что вы написали делается в сотню строк за час. Хватит уже сишечку мучать, 2015 год на дворе.

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

это и так делается на Си за час - просто вопрошающий про основы спрашивает

ae1234 ★★
()

Ну и еще вопрос по критическим секциям. В итоге у нас получается как минимум 2 очереди: 1-ая с активными девайсами 2-ая со списком сообщений для этих девайсов.

В основном таске где крутится libevent мы в первую очередь пихаем подключившегося клиента (в функции добавления клиента в очереди вешаем семафор, добавили семафор отдаем). Во втором таске, где идет выборка сообщений из базы при обнаружении новых сообщений добавляем их в очередь сообщений (также через своб функцию, которая свою очередь забирает на время добавления и потом отдает свой семафор). И в третьем таске где постоянно проверяется наличие сообщений для клиентов:

<цикл перебора активных девайсов> 
    <цикл перебора очереди сообщений>
        <если идентификатор девайса совпадает с идентификатором получателя сообщения>
            <отправка сообщения>
нужно так же забирать семафор сначала, который для очереди девайсов, и потом для очереди сообщений... на сколько такая реализация кривая?И как можно упростить этот процесс?

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

Может не совсем правильно выразился. Таск с libevent добавляет данные о подключившемся клиенте в очередь, а эта очередь уже может использоваться в другом таске, например при проверки наличия сообщения для клиента. И чтобы не было такого: что клиент отключился и его данные были убраны из очереди, а в этот момент другой таск запустил цикл проверки сообщения. До удаления из очереди забираем семафор и соотвествено цикл проверки сообщений будет ждать пока этот семафор освободится.

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

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

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

Хорошо, вот есть такая система: либэвент принимает сообщения и разбирает их, дальше складывает в очередь эта очередь выгружается в другой сервис, который говорит об этом клиенту, клиент видит, что устройство в сети - отправляет ему сообщение - это сообщение передается серверу на либэвенте как тогда без циклов и очередей сразу эту передать нужному устройству?

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

Устройства кучу бинарных пакетов шлют, на си уже есть готовая либа, которая разбирает их.

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