1 # Written by Ingar Arntzen
2 # see LICENSE.txt for license information
4 """This module implements a non-blocking event dispatcher for
8 import BaseLib.UPnP.common.asynchHTTPclient as httpclient
9 import BaseLib.UPnP.common.upnpsoap as upnpsoap
11 HTTP_NOTIFY_HEADER = u"""NOTIFY %(path)s HTTP/1.1\r
12 HOST: %(host)s:%(port)d\r
13 CONTENT-TYPE: text/xml\r
14 CONTENT-LENGTH: %(length)s\r
16 NTS: upnp:propchange\r
18 SEQ: %(key)s\r\n\r\n"""
20 _LOG_TAG = "HTTPClient"
22 ##############################################
24 ##############################################
26 class EventDispatcher:
28 Event Dispatcher wraps non-blocking httpClient to
29 provide a non-blocking event mechanism for the UPnP server.
32 def __init__(self, task_runner, logger=None):
33 self._tr = task_runner
34 self._httpclient = httpclient.AsynchHTTPClient(task_runner)
39 ##############################################
41 ##############################################
46 self._logger.log(_LOG_TAG, msg)
48 ##############################################
50 ##############################################
52 def dispatch(self, sid, event_key, callback_url, variables):
53 """Dispatch a new UPnP event message."""
55 # variables [(name, data)]
56 body = upnpsoap.create_event_message(variables)
57 # Create Notify Header
58 url = urlparse.urlparse(callback_url)
67 header = HTTP_NOTIFY_HEADER % dict_
68 # Dispatch Event Message
69 rid = self._httpclient.get_request_id()
70 self._httpclient.request(rid, url.hostname, url.port, header + body)
71 self._log("NOTIFY %s [%d]" %(url.hostname, event_key))
74 """Closes Event Dispacter along with its internal HTTP client."""
76 self._httpclient.close()
78 ##############################################
80 ##############################################
82 if __name__ == '__main__':
84 import BaseLib.UPnP.common.taskrunner as taskrunner
85 TASK_RUNNER = taskrunner.TaskRunner()
91 WORK_URL = "http://193.156.106.130:44444/events"
92 HOME_URL = "http://192.168.1.235:44444/events"
93 VARIABLES = [(u'arg1', u'data1'), (u'arg2', u'data2')]
97 def log(self, log_tag, msg):
102 EVD = EventDispatcher(TASK_RUNNER, logger=MockLogger())
103 EVD.dispatch(SID, KEY, WORK_URL, VARIABLES)
105 TASK_RUNNER.run_forever()
106 except KeyboardInterrupt: