From 1eae3af1906f95d9d2d76c205b61799d248f0e71 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 8 Jul 2014 16:45:43 -0300 Subject: Add base communication framework. --- src/leap/bitmask/backend/signaler_qt.py | 105 ++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 src/leap/bitmask/backend/signaler_qt.py (limited to 'src/leap/bitmask/backend/signaler_qt.py') diff --git a/src/leap/bitmask/backend/signaler_qt.py b/src/leap/bitmask/backend/signaler_qt.py new file mode 100644 index 00000000..cf49df91 --- /dev/null +++ b/src/leap/bitmask/backend/signaler_qt.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python +# encoding: utf-8 +import threading +import time + +from PySide import QtCore + +import zmq +from zmq.auth.thread import ThreadAuthenticator + +from leap.bitmask.backend.api import SIGNALS +from leap.bitmask.backend.utils import get_frontend_certificates + +import logging +logger = logging.getLogger(__name__) + + +class SignalerQt(QtCore.QThread): + """ + Signaling server. + Receives signals from the signaling client and emit Qt signals for the GUI. + """ + PORT = "5667" + BIND_ADDR = "tcp://127.0.0.1:%s" % PORT + + def __init__(self): + QtCore.QThread.__init__(self) + self._do_work = threading.Event() + self._do_work.set() + + def run(self): + """ + Start a loop to process the ZMQ requests from the signaler client. + """ + logger.debug("Running SignalerQt loop") + context = zmq.Context() + socket = context.socket(zmq.REP) + + # Start an authenticator for this context. + auth = ThreadAuthenticator(context) + auth.start() + auth.allow('127.0.0.1') + + # Tell authenticator to use the certificate in a directory + auth.configure_curve(domain='*', location=zmq.auth.CURVE_ALLOW_ANY) + public, secret = get_frontend_certificates() + socket.curve_publickey = public + socket.curve_secretkey = secret + socket.curve_server = True # must come before bind + + socket.bind(self.BIND_ADDR) + + while self._do_work.is_set(): + # Wait for next request from client + try: + request = socket.recv(zmq.NOBLOCK) + logger.debug("Received request: '{0}'".format(request)) + socket.send("OK") + self._process_request(request) + except zmq.ZMQError as e: + if e.errno != zmq.EAGAIN: + raise + time.sleep(0.01) + + logger.debug("SignalerQt thread stopped.") + + def stop(self): + """ + Stop the SignalerQt blocking loop. + """ + self._do_work.clear() + + def _process_request(self, request_json): + """ + Process a request and call the according method with the given + parameters. + + :param request_json: a json specification of a request. + :type request_json: str + """ + try: + request = zmq.utils.jsonapi.loads(request_json) + signal = request['signal'] + data = request['data'] + except Exception as e: + msg = "Malformed JSON data in Signaler request '{0}'. Exc: {1!r}" + msg = msg.format(request_json, e) + logger.critical(msg) + raise + + if signal not in SIGNALS: + logger.error("Unknown signal received, '{0}'".format(signal)) + return + + try: + qt_signal = getattr(self, signal) + except Exception: + logger.warning("Signal not implemented, '{0}'".format(signal)) + return + + logger.debug("Emitting '{0}'".format(signal)) + if data is None: + qt_signal.emit() + else: + qt_signal.emit(data) -- cgit v1.2.3 From 4d5e56dacf33465df5d195ada2855c86ee23a21f Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 19 Jun 2014 16:54:34 -0300 Subject: Add license headers. --- src/leap/bitmask/backend/signaler_qt.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'src/leap/bitmask/backend/signaler_qt.py') diff --git a/src/leap/bitmask/backend/signaler_qt.py b/src/leap/bitmask/backend/signaler_qt.py index cf49df91..dabd6662 100644 --- a/src/leap/bitmask/backend/signaler_qt.py +++ b/src/leap/bitmask/backend/signaler_qt.py @@ -1,5 +1,19 @@ -#!/usr/bin/env python -# encoding: utf-8 +# -*- coding: utf-8 -*- +# signaler_qt.py +# Copyright (C) 2013, 2014 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . import threading import time -- cgit v1.2.3 From d33e9a2bc07ccd983a1321b254cc27ca6be989a3 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 8 Jul 2014 17:01:18 -0300 Subject: Add file docstrings. --- src/leap/bitmask/backend/signaler_qt.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/leap/bitmask/backend/signaler_qt.py') diff --git a/src/leap/bitmask/backend/signaler_qt.py b/src/leap/bitmask/backend/signaler_qt.py index dabd6662..ce9c24f5 100644 --- a/src/leap/bitmask/backend/signaler_qt.py +++ b/src/leap/bitmask/backend/signaler_qt.py @@ -14,6 +14,10 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . +""" +Signaling server. +Receives signals from the signaling client and emit Qt signals for the GUI. +""" import threading import time -- cgit v1.2.3 From d8152277022eedf5a88c84cc5f099b2fc9ad6e46 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 9 Jul 2014 16:14:58 -0300 Subject: Comment out overly verbose logs for communication. --- src/leap/bitmask/backend/signaler_qt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/leap/bitmask/backend/signaler_qt.py') diff --git a/src/leap/bitmask/backend/signaler_qt.py b/src/leap/bitmask/backend/signaler_qt.py index ce9c24f5..4ec27a1e 100644 --- a/src/leap/bitmask/backend/signaler_qt.py +++ b/src/leap/bitmask/backend/signaler_qt.py @@ -72,7 +72,7 @@ class SignalerQt(QtCore.QThread): # Wait for next request from client try: request = socket.recv(zmq.NOBLOCK) - logger.debug("Received request: '{0}'".format(request)) + # logger.debug("Received request: '{0}'".format(request)) socket.send("OK") self._process_request(request) except zmq.ZMQError as e: @@ -116,7 +116,7 @@ class SignalerQt(QtCore.QThread): logger.warning("Signal not implemented, '{0}'".format(signal)) return - logger.debug("Emitting '{0}'".format(signal)) + # logger.debug("Emitting '{0}'".format(signal)) if data is None: qt_signal.emit() else: -- cgit v1.2.3 From 986ff80c16efea0e32ff78012b2fd3c95b83e179 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 15 Jul 2014 16:24:49 -0300 Subject: Replace QThread with threading.Thread. --- src/leap/bitmask/backend/signaler_qt.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'src/leap/bitmask/backend/signaler_qt.py') diff --git a/src/leap/bitmask/backend/signaler_qt.py b/src/leap/bitmask/backend/signaler_qt.py index 4ec27a1e..433f18ed 100644 --- a/src/leap/bitmask/backend/signaler_qt.py +++ b/src/leap/bitmask/backend/signaler_qt.py @@ -33,7 +33,7 @@ import logging logger = logging.getLogger(__name__) -class SignalerQt(QtCore.QThread): +class SignalerQt(QtCore.QObject): """ Signaling server. Receives signals from the signaling client and emit Qt signals for the GUI. @@ -42,11 +42,24 @@ class SignalerQt(QtCore.QThread): BIND_ADDR = "tcp://127.0.0.1:%s" % PORT def __init__(self): - QtCore.QThread.__init__(self) + QtCore.QObject.__init__(self) + + # Note: we use a plain thread instead of a QThread since works better. + # The signaler was not responding on OSX if the worker loop was run in + # a QThread. + # Possibly, ZMQ was not getting cycles to do work because Qt not + # receiving focus or something. + self._worker_thread = threading.Thread(target=self._run) self._do_work = threading.Event() + + def start(self): + """ + Start the worker thread for the signaler server. + """ self._do_work.set() + self._worker_thread.start() - def run(self): + def _run(self): """ Start a loop to process the ZMQ requests from the signaler client. """ -- cgit v1.2.3