diff --git a/agkyra/__init__.py b/agkyra/__init__.py
index bcbf9d2c9c65486c62b7c93428b130fabb78cb6d..29e2b7ef88d0d36658d654a2ff2d0b85d1fa8b51 100644
--- a/agkyra/__init__.py
+++ b/agkyra/__init__.py
@@ -7,6 +7,9 @@ from tempfile import NamedTemporaryFile
 import subprocess
 import json
 from os.path import abspath
+from threading import Thread
+from hashlib import sha256
+from os import urandom
 
 from ws4py.client import WebSocketBaseClient
 
@@ -14,51 +17,58 @@ from ws4py.client import WebSocketBaseClient
 class GUILauncher(WebSocketBaseClient):
     """Launch the GUI when the helper server is ready"""
 
-    def __init__(self, port, gui_exec_path, token):
-        super(GUILauncher, self).__init__('ws://localhost:%s' % port)
-        self.port = port
+    def __init__(self, addr, gui_exec_path, token):
+        """Initialize the GUI Launcher"""
+        super(GUILauncher, self).__init__(addr)
+        self.addr = addr
         self.gui_exec_path = gui_exec_path
         self.token = token
 
     def handshake_ok(self):
+        """If handshake is OK, the helper is UP, so the GUI can be launched
+        If the GUI is terminated for some reason, the WebSocket is closed"""
         with NamedTemporaryFile(mode='a+') as fp:
-            json.dump(dict(token=self.token, port=self.port), fp)
+            json.dump(dict(token=self.token, address=self.addr), fp)
             fp.flush()
+            # subprocess.call blocks the execution
             subprocess.call([
                 '/home/saxtouri/node-webkit-v0.11.6-linux-x64/nw',
                 abspath('gui/gui.nw'),
                 fp.name])
+        self.close()
 
 
-class Helper(object):
-    """Coordination between the GUI and the Syncer instances
+def setup_server(token, port=0):
+    """Setup and return the helper server"""
+    WebSocketProtocol.token = token
+    server = make_server(
+        '', port,
+        server_class=WSGIServer,
+        handler_class=WebSocketWSGIRequestHandler,
+        app=WebSocketWSGIApplication(handler_cls=WebSocketProtocol))
+    server.initialize_websockets_manager()
+    # self.port = server.server_port
+    return server
 
-    Setup a minimal server at a ephemeral port, create a random token, dump
-    this information in a local file and launch the GUI with this file as a
-    parameter.
-    Then the GUI connects and a WebSocket is established.
 
-    """
+def random_token():
+    return 'random token'
 
-    def __init__(self, gui_exec_path, port=0):
-        self.server = self.setup_server(port)
-        self.port = self.server.server_port
-        self.token = 'some random token'
-        self.gui_exec_path = gui_exec_path
 
-    def setup_server(self, port=0):
-        server = make_server(
-            '', port,
-            server_class=WSGIServer,
-            handler_class=WebSocketWSGIRequestHandler,
-            app=WebSocketWSGIApplication(handler_cls=WebSocketProtocol))
-        server.initialize_websockets_manager()
-        # self.port = server.server_port
-        return server
+def run(gui_exec_path):
+    """Prepare helper and GUI and run them in the proper order"""
+    token = sha256(urandom(256)).hexdigest()
+    server = setup_server(token)
+    addr = 'ws://localhost:%s' % server.server_port
+
+    gui = GUILauncher(addr, gui_exec_path, token)
+    Thread(target=gui.connect).start()
 
-    def run(self):
-        gui = GUILauncher(self.port, self.gui_exec_path, self.token)
-        gui.connect()
-        self.server.serve_forever()
+    try:
+        server.serve_forever()
+    except KeyboardInterrupt:
+        print 'Shutdown GUI'
+        gui.close()
 
-Helper('ls').run()
+if __name__ == '__main__':
+    run('/home/saxtouri/node-webkit-v0.11.6-linux-x64/nw gui.nw')
diff --git a/agkyra/gui/protocol.js b/agkyra/gui/protocol.js
index 897245957f4ecf6fba8e582652e43aaea7ec5508..c6a56a361dfa05ef9e4dae4c27fe30efbc88d9d8 100644
--- a/agkyra/gui/protocol.js
+++ b/agkyra/gui/protocol.js
@@ -4,95 +4,93 @@ var gui = require('nw.gui');
 var fs = require('fs');
 var cnf = JSON.parse(fs.readFileSync(gui.App.argv[0], encoding='utf-8'));
 
-setTimeout(function() {
-  // Connect to helper
-  var socket = new WebSocket('ws://localhost:' + cnf['port']);
-  socket.onopen = function() {
-    console.log('Connecting to helper');
-    this.send(cnf['token']);
-  }
-  socket.onmessage = function(e) {
-    console.log('message', e.data);
-  };
-  socket.onerror = function () {
-      console.log('GUI and helper cannot communicate, quiting');
-      gui.Window.get().close();
-  }
+// Connect to helper
+var socket = new WebSocket(cnf['address']);
+socket.onopen = function() {
+  console.log('Connecting to helper');
+  this.send(cnf['token']);
+}
+socket.onmessage = function(e) {
+  console.log('message', e.data);
+};
+socket.onerror = function () {
+    console.log('GUI and helper cannot communicate, quiting');
+    gui.Window.get().close();
+}
 
-  // Setup GUI
-  var windows = {
-    "settings": null,
-    "about": null,
-    "index": gui.Window.get()
-  }
-  function closeWindows() {
-    for (win in windows) if (windows[win]) windows[win].close();
-  }
+// Setup GUI
+var windows = {
+  "settings": null,
+  "about": null,
+  "index": gui.Window.get()
+}
+function closeWindows() {
+  for (win in windows) if (windows[win]) windows[win].close();
+}
 
-  // GUI components
-  var tray = new gui.Tray({
-    tooltip: 'Paused (0% synced)',
-    title: 'Agkyra syncs with Pithos+',
-    icon: 'icons/tray.png'
-  });
+// GUI components
+var tray = new gui.Tray({
+  tooltip: 'Paused (0% synced)',
+  title: 'Agkyra syncs with Pithos+',
+  icon: 'icons/tray.png'
+});
 
-  var menu = new gui.Menu();
+var menu = new gui.Menu();
 
-  // See contents
-  menu.append(new gui.MenuItem({type: 'separator'}));
-  menu.append(new gui.MenuItem({
-    label: 'Open local folder',
-    icon: 'icons/folder.png',
-    click: function () {gui.Shell.showItemInFolder('.');}
-  }));
+// See contents
+menu.append(new gui.MenuItem({type: 'separator'}));
+menu.append(new gui.MenuItem({
+  label: 'Open local folder',
+  icon: 'icons/folder.png',
+  click: function () {gui.Shell.showItemInFolder('.');}
+}));
 
-  menu.append(new gui.MenuItem({
-    label: 'Launch Pithos+ page',
-    icon: 'icons/pithos.png',
-    click: function () {
-      gui.Shell.openExternal('https://pithos.okeanos.grnet.gr');
-    }
-  }));
+menu.append(new gui.MenuItem({
+  label: 'Launch Pithos+ page',
+  icon: 'icons/pithos.png',
+  click: function () {
+    gui.Shell.openExternal('https://pithos.okeanos.grnet.gr');
+  }
+}));
 
-  menu.append(new gui.MenuItem({
-    label: 'Recently changed files',
-    icon: 'icons/logs.png',
-    click: function () {gui.Shell.openItem('logs.txt');}
-  }));
+menu.append(new gui.MenuItem({
+  label: 'Recently changed files',
+  icon: 'icons/logs.png',
+  click: function () {gui.Shell.openItem('logs.txt');}
+}));
 
-  // Settings and About
-  menu.append(new gui.MenuItem({type: 'separator'}));
-  menu.append(new gui.MenuItem({
-    label: 'Settings',
-    icon: 'icons/settings.png',
-    click: function () {
-      if (windows['settings']) windows['settings'].close();
-      windows['settings'] = gui.Window.open("settings.html", {
-        "toolbar": false, "focus": true});
-    }
-  }));
+// Settings and About
+menu.append(new gui.MenuItem({type: 'separator'}));
+menu.append(new gui.MenuItem({
+  label: 'Settings',
+  icon: 'icons/settings.png',
+  click: function () {
+    if (windows['settings']) windows['settings'].close();
+    windows['settings'] = gui.Window.open("settings.html", {
+      "toolbar": false, "focus": true});
+  }
+}));
 
-  menu.append(new gui.MenuItem({
-    label: 'About',
-    icon: 'icons/about.png',
-    click: function () {
-      if (windows['about']) windows['about'].close();
-      windows['about'] = gui.Window.open("about.html", {
-        "toolbar": false, "resizable": false, "focus": true});
-    }
-  }));
+menu.append(new gui.MenuItem({
+  label: 'About',
+  icon: 'icons/about.png',
+  click: function () {
+    if (windows['about']) windows['about'].close();
+    windows['about'] = gui.Window.open("about.html", {
+      "toolbar": false, "resizable": false, "focus": true});
+  }
+}));
 
-  // Quit
-  menu.append(new gui.MenuItem({type: 'separator'}));
-  menu.append(new gui.MenuItem({
-    label: 'Quit Agkyra',
-    icon: 'icons/exit.png',
-    click: function () {
-      console.log('Exiting client');
-      console.log('Exiting GUI');
-      closeWindows()
-    }
-  }));
+// Quit
+menu.append(new gui.MenuItem({type: 'separator'}));
+menu.append(new gui.MenuItem({
+  label: 'Quit Agkyra',
+  icon: 'icons/exit.png',
+  click: function () {
+    console.log('Exiting client');
+    console.log('Exiting GUI');
+    closeWindows()
+  }
+}));
 
-  tray.menu = menu;
-}, 100); // Timeout in milliseconds
+tray.menu = menu;
diff --git a/agkyra/protocol.py b/agkyra/protocol.py
index 81e5fe8375edc5041dcc9b4e4e91142c060e9ac3..5454b449f0ed8ee13ff0c92ae071c68260dc3a30 100644
--- a/agkyra/protocol.py
+++ b/agkyra/protocol.py
@@ -36,6 +36,14 @@ class WebSocketProtocol(WebSocket):
         {"ERROR": <error code>, "MESSAGE": <message>}
     """
 
-    def __init__(self, *args, **kwargs):
-        super(WebSocketProtocol, self).__init__(*args, **kwargs)
-        print 'lala'
+    token = None
+
+    def opened(self):
+        print 'A connection is open', self.token
+
+    def closed(self, *args):
+        print 'A connection is closed', args
+
+    def received_message(self, message):
+        print 'Got message', message
+        self.send(message)