Size: a a a

2020 February 08

D

Disi in Modern::Perl
Привет! У меня есть задача:
в Mojolicious на POST приходит реквест с json данными
Мне нужно эти данные броадкастом разослать в вебсокете.

Как провернуть этот обмен данными между POST и WS?
(как из post вызвать send вебсокета)
источник

AH

Anton Horodchuk in Modern::Perl
Disi
Привет! У меня есть задача:
в Mojolicious на POST приходит реквест с json данными
Мне нужно эти данные броадкастом разослать в вебсокете.

Как провернуть этот обмен данными между POST и WS?
(как из post вызвать send вебсокета)
Странный вопрос, учитывая что это всё в рамках одного процесса.

Код для наглядности, я просто взял какой-то из "Writing websocket chat using Mojolicious::Lite" из просторов интернета, и убрал лишнее

# регистрируем клиентов при подключении

my $clients = {};
websocket '/echo' => sub {
   my $self = shift;

   app->log->debug(sprintf 'Client connected: %s', $self->tx);
   my $id = sprintf "%s", $self->tx;
   $clients->{$id} = $self->tx;

   $self->on(finish => sub {
       app->log->debug('Client disconnected');
       delete $clients->{$id};
   });
};


# на POST рассылаем по сохранённым клиентах

post '/broadcast' => sub {
 my $self = shift;

 my $msg = getMessageFromPayload(...)

 for (keys %$clients){
   $clients->{$_}->send({json => {
               hms  => $dt->hms,
               text => $msg,
           }});
 }
}
источник

D

Disi in Modern::Perl
ок
источник

AK

Andrey Konovalov in Modern::Perl
Anton Horodchuk
Странный вопрос, учитывая что это всё в рамках одного процесса.

Код для наглядности, я просто взял какой-то из "Writing websocket chat using Mojolicious::Lite" из просторов интернета, и убрал лишнее

# регистрируем клиентов при подключении

my $clients = {};
websocket '/echo' => sub {
   my $self = shift;

   app->log->debug(sprintf 'Client connected: %s', $self->tx);
   my $id = sprintf "%s", $self->tx;
   $clients->{$id} = $self->tx;

   $self->on(finish => sub {
       app->log->debug('Client disconnected');
       delete $clients->{$id};
   });
};


# на POST рассылаем по сохранённым клиентах

post '/broadcast' => sub {
 my $self = shift;

 my $msg = getMessageFromPayload(...)

 for (keys %$clients){
   $clients->{$_}->send({json => {
               hms  => $dt->hms,
               text => $msg,
           }});
 }
}
Есть же values %{$clients}, плюс я бы не стал каждый раз заново формировать один и тот же json, если для каждого клиента он один и тот же
источник

AK

Andrey Konovalov in Modern::Perl
А, ну тестовый пример... Но всё же ;)
источник

AH

Anton Horodchuk in Modern::Perl
Andrey Konovalov
Есть же values %{$clients}, плюс я бы не стал каждый раз заново формировать один и тот же json, если для каждого клиента он один и тот же
Согласен )
источник

AS

Alexey Stavrov in Modern::Perl
Anton Horodchuk
Странный вопрос, учитывая что это всё в рамках одного процесса.

Код для наглядности, я просто взял какой-то из "Writing websocket chat using Mojolicious::Lite" из просторов интернета, и убрал лишнее

# регистрируем клиентов при подключении

my $clients = {};
websocket '/echo' => sub {
   my $self = shift;

   app->log->debug(sprintf 'Client connected: %s', $self->tx);
   my $id = sprintf "%s", $self->tx;
   $clients->{$id} = $self->tx;

   $self->on(finish => sub {
       app->log->debug('Client disconnected');
       delete $clients->{$id};
   });
};


# на POST рассылаем по сохранённым клиентах

post '/broadcast' => sub {
 my $self = shift;

 my $msg = getMessageFromPayload(...)

 for (keys %$clients){
   $clients->{$_}->send({json => {
               hms  => $dt->hms,
               text => $msg,
           }});
 }
}
И откуда же это следует, что один процесс?

Кажется в один процесс работает только daemon и morbo, которые как раз не используются на проде
источник

AK

Andrey Konovalov in Modern::Perl
Disi
Привет! У меня есть задача:
в Mojolicious на POST приходит реквест с json данными
Мне нужно эти данные броадкастом разослать в вебсокете.

Как провернуть этот обмен данными между POST и WS?
(как из post вызвать send вебсокета)
Redis pub/sub или Redis streams. Как вариант
источник

AK

Andrey Konovalov in Modern::Perl
Все процессы подписываются, если в сообщении есть pid отправившего, то можно сделать так, что он не будет ждать, когда ему из redis прилетит то, что он сам только что запулил туда, а сразу опубликует всем своим клиентам
источник

AH

Anton Horodchuk in Modern::Perl
Alexey Stavrov
И откуда же это следует, что один процесс?

Кажется в один процесс работает только daemon и morbo, которые как раз не используются на проде
Да ниоткуда, как и обратное
источник

AK

Andrey Konovalov in Modern::Perl
Alexey Stavrov
И откуда же это следует, что один процесс?

Кажется в один процесс работает только daemon и morbo, которые как раз не используются на проде
Morbo вроде заменяет гипножабу же, это он когда-то был чисто для дебага
источник

AS

Alexey Stavrov in Modern::Perl
Andrey Konovalov
Morbo вроде заменяет гипножабу же, это он когда-то был чисто для дебага
Сейчас морбо для чего-то другого?
источник

AH

Anton Horodchuk in Modern::Perl
Если в разных процессах, то поверх того, что я скинул, добавляется IPC, своё или в виде внешнего брокера.
Главное, что ничего страшного в задаче нет
источник

AK

Andrey Konovalov in Modern::Perl
Alexey Stavrov
Сейчас морбо для чего-то другого?
Могу ошибаться. Просто читал в чейнджлоге или блоге Моджо о том, что роль морбо повышается, а от гипножабы Ригель вообще хочет избавиться
источник

AK

Andrey Konovalov in Modern::Perl
https://mojolicious.org/perldoc/morbo хм, вроде всё же development
источник

c

crux in Modern::Perl
Disi
Привет! У меня есть задача:
в Mojolicious на POST приходит реквест с json данными
Мне нужно эти данные броадкастом разослать в вебсокете.

Как провернуть этот обмен данными между POST и WS?
(как из post вызвать send вебсокета)
При установке соединения с вебсокетом подписываешься на свой эвент, в обработчике отправляешь полученное в сокет. В контроллере POST кидаешь этот эвент с сообщением в данных.

В гипножабе с несколькими воркерами это тоже будет работать, эвенты прокидываются на все воркеры.

Но это если у тебя один сервер. Если расчет на несколько с неким балансировщиком, то, как уже предложили - например, Redis pubsub или какой-нибудь MQ. Только для моджо нет поддержки редис кластера, что для меня лично недавно было неприятным сюрпризом.
источник

AP

Anton Petrusevich in Modern::Perl
да, MQ нужна как только появляются вебсокеты и сообщения в них
источник

AP

Anton Petrusevich in Modern::Perl
хоть самопальная, хоть "заимствованная" из редиса, кролика и прочих постгресов
источник

AK

Andrey Konovalov in Modern::Perl
crux
При установке соединения с вебсокетом подписываешься на свой эвент, в обработчике отправляешь полученное в сокет. В контроллере POST кидаешь этот эвент с сообщением в данных.

В гипножабе с несколькими воркерами это тоже будет работать, эвенты прокидываются на все воркеры.

Но это если у тебя один сервер. Если расчет на несколько с неким балансировщиком, то, как уже предложили - например, Redis pubsub или какой-нибудь MQ. Только для моджо нет поддержки редис кластера, что для меня лично недавно было неприятным сюрпризом.
Любой модуль для Redis с поддержкой EV или AnyEvent подойдёт. Разве что какой-то единственный для AnyEvent был при этом ещё и очень медленным
источник

AK

Andrey Konovalov in Modern::Perl
Просто штуки типа Redis::Fast почему игнорируют существование циклов событий.
источник