712672389a9a6ceb5f465e054356f1a91c993174
[leap_pycommon.git] / src / leap / common / events / server.py
1 # -*- coding: utf-8 -*-
2 # server.py
3 # Copyright (C) 2013 LEAP
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18
19 """
20 The server for the events mechanism.
21 """
22
23
24 import logging
25 import platform
26 import txzmq
27
28 from leap.common.zmq_utils import zmq_has_curve
29
30 from leap.common.events.zmq_components import TxZmqServerComponent
31
32
33 if zmq_has_curve() or platform.system() == "Windows":
34     # Windows doesn't have icp sockets, we need to use always tcp
35     EMIT_ADDR = "tcp://127.0.0.1:9000"
36     REG_ADDR = "tcp://127.0.0.1:9001"
37 else:
38     EMIT_ADDR = "ipc:///tmp/leap.common.events.socket.0"
39     REG_ADDR = "ipc:///tmp/leap.common.events.socket.1"
40
41
42 logger = logging.getLogger(__name__)
43
44
45 def ensure_server(emit_addr=EMIT_ADDR, reg_addr=REG_ADDR):
46     """
47     Make sure the server is running in the given addresses.
48
49     :param emit_addr: The address in which to receive events from clients.
50     :type emit_addr: str
51     :param reg_addr: The address to which publish events to clients.
52     :type reg_addr: str
53
54     :return: an events server instance
55     :rtype: EventsServer
56     """
57     _server = EventsServer(emit_addr, reg_addr)
58     return _server
59
60
61 class EventsServer(TxZmqServerComponent):
62     """
63     An events server that listens for events in one address and publishes those
64     events in another address.
65     """
66
67     def __init__(self, emit_addr, reg_addr):
68         """
69         Initialize the events server.
70
71         :param emit_addr: The address in which to receive events from clients.
72         :type emit_addr: str
73         :param reg_addr: The address to which publish events to clients.
74         :type reg_addr: str
75         """
76         TxZmqServerComponent.__init__(self)
77         # bind PULL and PUB sockets
78         self._pull, self.pull_port = self._zmq_bind(
79             txzmq.ZmqPullConnection, emit_addr)
80         self._pub, self.pub_port = self._zmq_bind(
81             txzmq.ZmqPubConnection, reg_addr)
82         # set a handler for arriving messages
83         self._pull.onPull = self._onPull
84
85     def _onPull(self, message):
86         """
87         Callback executed when a message is pulled from a client.
88
89         :param message: The message sent by the client.
90         :type message: str
91         """
92         event, content = message[0].split(b"\0", 1)
93         logger.debug("Publishing event: %s" % event)
94         self._pub.publish(content, tag=event)