diff --git a/lib/PiTube.pm b/lib/PiTube.pm
index c9b64fdd54d7ef49c7e0cfae6ea9f19881abdecd..863972edf962739b4ecab1377a41bf6f90d0129f 100644
--- a/lib/PiTube.pm
+++ b/lib/PiTube.pm
@@ -30,6 +30,7 @@ sub startup {
     ;
     $pg->migrations->from_file($self->home . '/sql/migrations.sql');
     $pg->migrations->migrate();
+    $self->helper( pg => sub { return $pg; } );
 
     # Spojeni s databazi
     my $schema = PiTube::Schema->connect($cfg->{database});
@@ -84,6 +85,8 @@ sub startup {
 #    $r->put('/streams/:id')->over( is => 'administrator'  )->to('Stream#update');
 #    $r->delete('/streams/:id')->over( is => 'administrator'  )->to('Stream#delete');
 
+    $r->websocket('/ws/streams')->to('Stream#ws');
+
     $r->get('/oauth2')->to('OAuth2#callback');
     $r->get('/logout')->to('OAuth2#do_logout');
     $r->post('/callback/rtmp')->to('Nginx#callback_rtmp');
diff --git a/lib/PiTube/Controller/Nginx.pm b/lib/PiTube/Controller/Nginx.pm
index f84573d7134c0c3ea08ec1f5f106db21ecf4b500..789af4a5fbc2335a5f6d46772e528b845ffa4d48 100644
--- a/lib/PiTube/Controller/Nginx.pm
+++ b/lib/PiTube/Controller/Nginx.pm
@@ -7,7 +7,6 @@ use constant HLS => qr/hls\/([a-z0-9\-]+)(_\w+)?(\/\w+)?\.(m3u8|ts)$/i;
 sub callback_rtmp {
     my $c = shift;
     my $pubsub = Mojo::Pg::PubSub->new(pg => $c->pg);
-    $pubsub = $pubsub->json('messages');
 
     if ( $c->param('call') =~ /publish/ ) {
         my $name = $c->param('name');
@@ -38,10 +37,10 @@ sub callback_rtmp {
             is_live          => ( $c->param('call') =~ /done/ ) ? 'f':'t',
         });
 
-        $pubsub->notify( messages => {
-            call   => $c->param('call'),
+        $pubsub->json('streams')->notify( streams => {
+            call      => $c->param('call'),
+            stream_id => $stream->id,
         });
-
     }
 
     $c->render( status => 204, text => '' );
diff --git a/lib/PiTube/Controller/Stream.pm b/lib/PiTube/Controller/Stream.pm
index 94d390325a615497a0713d04e6102a8f34752808..db70a9dfd8ff804779a06f9ec67cc732c588a214 100644
--- a/lib/PiTube/Controller/Stream.pm
+++ b/lib/PiTube/Controller/Stream.pm
@@ -1,6 +1,9 @@
 package PiTube::Controller::Stream;
+
+use feature 'signatures';
 use Mojo::Base 'Mojolicious::Controller';
 use Mojo::UserAgent;
+use Mojo::Pg::PubSub;
 
 use constant CONTENT_TYPE => {
     m3u8 => 'application/vnd.apple.mpegurl',
@@ -175,6 +178,23 @@ sub recording {
     $c->render( json => { recording => $stream->recording  } );
 }
 
+sub ws {
+    my $c = shift;
+
+    $c->inactivity_timeout(300);
+
+    my $pubsub = Mojo::Pg::PubSub->new(pg => $c->pg);
+
+    $pubsub->listen(streams => sub($pubsub, $payload) {
+        $c->send($payload);
+    });
+
+    $c->on(finish => sub ($c, $code, $reason = undef) {
+        $pubsub->unlisten('streams');
+        $c->app->log->debug("WebSocket closed with status $code");
+    });
+}
+
 1;
 
 __END__
diff --git a/nginx.conf b/nginx.conf
index eb42334a7236f97e3626439439153b7808b7323e..0460dd10e88c9fad2e5198e6a2835d8c649fda92 100644
--- a/nginx.conf
+++ b/nginx.conf
@@ -90,6 +90,14 @@ http {
             expires 24h;
         }
 
+        location /ws {
+            proxy_pass http://pitube:3000/ws;
+            proxy_http_version 1.1;
+            proxy_set_header Upgrade $http_upgrade;
+            proxy_set_header Connection "Upgrade";
+            proxy_set_header Host $host;
+        }
+
         location / {
             proxy_pass http://pitube:3000/;
             add_header Access-Control-Allow-Origin *;
diff --git a/pi_tube.conf b/pi_tube.conf
index 2f97f5756a8cca6387930bd6ded600aabdc5c392..6ea5005346281c60da12d6df93e4636cf51b0d4c 100644
--- a/pi_tube.conf
+++ b/pi_tube.conf
@@ -38,4 +38,5 @@
   },
   matomo_id         => $ENV{MATOMO_ID} // 0,
   base_url          => $ENV{BASE_URL},
+  ws_url            => $ENV{WS_URL},
 };