diff --git a/lib/PiTube/Controller/Stream.pm b/lib/PiTube/Controller/Stream.pm
index db70a9dfd8ff804779a06f9ec67cc732c588a214..7fea7295c8d68b039f15574ddfbea468f87ccf45 100644
--- a/lib/PiTube/Controller/Stream.pm
+++ b/lib/PiTube/Controller/Stream.pm
@@ -1,9 +1,11 @@
 package PiTube::Controller::Stream;
 
 use feature 'signatures';
+no warnings qw{ experimental::signatures };
 use Mojo::Base 'Mojolicious::Controller';
 use Mojo::UserAgent;
 use Mojo::Pg::PubSub;
+use Data::Random qw(rand_chars);
 
 use constant CONTENT_TYPE => {
     m3u8 => 'application/vnd.apple.mpegurl',
@@ -64,6 +66,8 @@ sub player {
         $c->session->{user}
     );
 
+    $c->session->{user}{wid} ||= rand_chars( set => 'alphanumeric', size => 16 );
+
     # stream
     my $stream = $c->schema->resultset('Stream_view')->find({
         key => $c->stash->{key}
@@ -178,22 +182,6 @@ 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;
 
diff --git a/lib/PiTube/Controller/Websockets.pm b/lib/PiTube/Controller/Websockets.pm
new file mode 100644
index 0000000000000000000000000000000000000000..26c1bef4be11efa1376e0ded2004d3295934ffa1
--- /dev/null
+++ b/lib/PiTube/Controller/Websockets.pm
@@ -0,0 +1,37 @@
+package PiTube::Controller::Websockets;
+
+use experimental 'signatures';
+
+use Mojo::Base 'Mojolicious::Controller';
+use Mojo::Pg::PubSub;
+
+use constant SOCKET_INACTIVITY_TIMEOUT => 300;
+
+sub main {
+    my $c = shift;
+
+    $c->inactivity_timeout(SOCKET_INACTIVITY_TIMEOUT);
+
+    if ($c->req->headers->header('Sec-WebSocket-Extensions') =~ /permessage-deflate/) {
+        $c->tx->compressed(1);
+        $c->res->headers->add('Sec-WebSocket-Extensions' => 'permessage-deflate');
+    }
+
+    my $pubsub = Mojo::Pg::PubSub->new(pg => $c->pg);
+
+    $pubsub->listen(streams => sub($pubsub, $payload) {
+        $c->send($payload);
+    });
+
+    $c->on(json => sub( $c, $message ) {
+        if ( $message->{event} eq 'KEEPALIVE' ) {
+        }
+    });
+
+    $c->on(finish => sub ($c, $code, $reason = undef) {
+        $pubsub->unlisten('streams');
+        $c->app->log->debug("WebSocket closed with status $code");
+    });
+}
+
+1;
diff --git a/templates/live.html.ep b/templates/live.html.ep
index 0cbb79d94d617945a7baa10875e02f2e5d18bdf2..4b360ad2b77cb0dcbfca03550c72bfe6f3048ad9 100644
--- a/templates/live.html.ep
+++ b/templates/live.html.ep
@@ -1,7 +1,6 @@
 % layout 'default';
 % title 'Živé vysílání';
 
-<div class="container pt-2 lg:pb-2 ">
 <table id="Streams"
     class="table table--bordered"
     data-row-style="rowStyle"
@@ -16,7 +15,6 @@
     </tr>
   </thead>
 </table>
-</div>
 
 <script>
 $('#Streams').bootstrapTable({
@@ -62,11 +60,36 @@ function rowStyle(row, index) {
     }
 }
 
-var ws = new WebSocket('<%= $c->config->{ws_url} %>/streams');
+function connect() {
+  var ws = new WebSocket('<%= $c->config->{ws_url} %>');
 
-ws.onmessage = function (event) {
-  console.log(event.data);
-  $('#Streams').bootstrapTable('refresh', {silent: true})
-};
+/*
+  ws.onopen = function() {
+    // subscribe to some channels
+    ws.send(JSON.stringify({
+        //.... some message the I must send when I connect ....
+    }));
+  };
+*/
+
+  ws.onmessage = function (event) {
+    console.log(event.data);
+    $('#Streams').bootstrapTable('refresh', {silent: true})
+  };
+
+  ws.onclose = function(e) {
+    console.log('Socket is closed. Reconnect will be attempted in 1 second.', e.reason);
+    setTimeout(function() {
+      connect();
+    }, 1000);
+  };
+
+  ws.onerror = function(err) {
+    console.error('Socket encountered error: ', err.message, 'Closing socket');
+    ws.close();
+  };
+}
+
+connect();
 
 </script>