Commits

Ginés Martínez Sánchez committed 1114523 Draft

developing websocket

Comments (0)

Files changed (5)

ginsfsm/examples/sockjs/test_sockjs_server.ini

 application = wsgi-application
 GSock.trace_dump = true
 # GObj: super-global setter.
-GObj.trace_mach = true
+#GObj.trace_mach = true
+GObj.trace_traverse = true
 GWebSocket.trace_mach = true
 
 [app:wsgi-application]
     'trace_mach': [bool, False, 0, None, 'Display simple machine activity'],
     # logger is inherited from SMachine.
     'logger': [None, None, 0, None, ''],
+    'trace_traverse': [bool, False, 0, None, 'Display traverse search'],
     'create_gobj': [None, None, 0, None, ''],
     'destroy_gobj': [None, None, 0, None, ''],
     'enqueue_event': [None, None, 0, None, ''],
     def __getitem__(self, name):
         """ Enable gobjs tree to work with Pyramid traversal URL dispatch.
         """
+        trace_traverse = self.trace_traverse
+        if trace_traverse:
+            logger = self.logger
+            logger.info("==> TRAVERSING('%s') -> %s" % (
+                name, self.resource_path()))
+
         if name is None:
             raise KeyError('Parameter name cannot be None')
         # Firstly search no re_name
                 continue
             else:
                 if gobj.name == name:
+                    if trace_traverse:
+                        logger.info("    TRAVERSING FOUND!")
                     return gobj
 
         # Secondly search re_name
                 if gobj._re_compiled_name.match(name) is not None:
                     # this gobj has been got as re_matched_name.
                     gobj.re_matched_name = name
+                    if trace_traverse:
+                        logger.info("    TRAVERSING %s FOUND RE!" % name)
                     return gobj
             else:
                 continue
+        if trace_traverse:
+            logger.info("<== TRAVERSING('%s') -> %s END!" % (
+                name, self.resource_path()))
         raise KeyError('No such child named %s' % name)
 
     def __iter__(self):

ginsfsm/protocols/sockjs/server/c_static.py

+# -*- encoding: utf-8 -*-
+""" basehandler
+"""
+
+import random
+import hashlib
+from sys import maxint
+
+from pyramid.view import view_config
+
+from ginsfsm.protocols.sockjs.server.protocol import json
+from ginsfsm.protocols.sockjs.server.basehandler import (
+    PreflightHandler,
+    BaseHandler,
+)
+from ginsfsm.gobj import GObj
+
+
+#----------------------------------------------------------------#
+#                   Info GClass
+#----------------------------------------------------------------#
+GINFO_GCONFIG = {
+    'sockjs_server': [None, None, 0, None, ""],
+}
+
+
+class GInfo(GObj):
+    """  GInfo GObj.
+    """
+    def __init__(self):
+        GObj.__init__(self, {}, GINFO_GCONFIG)
+
+    def start_up(self):
+        """ Initialization zone.
+        """
+        # Info Test views
+        """
+        self.sockjs_server.pyramid_config.add_view(
+            context=GInfo,
+            name='',
+            view=InfoHandler,
+            attr='get',
+            path_info=self.resource_path(),
+            request_method='GET',
+            permission=self.sockjs_server.permission,
+        )
+        self.sockjs_server.pyramid_config.add_view(
+            context=GInfo,
+            name='',
+            view=InfoHandler,
+            attr='options',
+            path_info=self.resource_path(),
+            request_method='OPTIONS',
+            permission=self.sockjs_server.permission,
+        )
+        """
+
+
+#----------------------------------------------------------------#
+#                   Info views
+#----------------------------------------------------------------#
+@view_config(
+    context=GInfo,
+    name='',
+    attr='get',
+    request_method='GET',
+)
+@view_config(
+    context=GInfo,
+    name='',
+    attr='options',
+    request_method='OPTIONS',
+)
+class InfoHandler(PreflightHandler):
+    """SockJS 0.2+ /info handler"""
+    def __init__(self, context, request):
+        PreflightHandler.__init__(self, context, request)
+        self.access_methods = 'OPTIONS, GET'
+
+    def get(self):
+        response = self.response
+        response.content_type = 'application/json'
+        response.charset = 'UTF-8'
+        self.preflight()
+        self.disable_cache()
+
+        info = {
+            'websocket':
+                'websocket' not in self.context.sockjs_server.disabled_transports,
+            'cookie_needed': self.context.sockjs_server.cookie_needed,
+            'origins': ['*:*'],
+            'entropy': random.randint(0, maxint),
+        }
+        response.body = json.dumps(info)
+        return response
+
+
+#----------------------------------------------------------------#
+#                   IFrame GClass
+#----------------------------------------------------------------#
+GIFRAME_GCONFIG = {
+    'sockjs_server': [None, None, 0, None, ""],
+}
+
+
+class GIFrame(GObj):
+    """  GIFrame GObj.
+    """
+    def __init__(self):
+        GObj.__init__(self, {}, GIFRAME_GCONFIG)
+
+    def start_up(self):
+        """ Initialization zone.
+        """
+        """
+        self.sockjs_server.pyramid_config.add_view(
+            context=GIFrame,
+#            name='',
+            view=IFrameHandler,
+            attr='get',
+            path_info=self.resource_path(),
+            request_method='GET',
+            permission=self.sockjs_server.permission,
+        )
+        """
+
+#----------------------------------------------------------------#
+#                   IFrame views
+#----------------------------------------------------------------#
+IFRAME_TEXT = """<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+  <script>
+    document.domain = document.domain;
+    _sockjs_onload = function(){SockJS.bootstrap_iframe();};
+  </script>
+  <script src="%s"></script>
+</head>
+<body>
+  <h2>Don't panic!</h2>
+  <p>This is a SockJS hidden iframe. It's used for cross domain magic.</p>
+</body>
+</html>
+""".strip()
+
+
+@view_config(
+    context=GIFrame,
+    name='',
+    attr='get',
+    request_method='GET',
+)
+class IFrameHandler(BaseHandler):
+    """SockJS IFrame page handler"""
+    def get(self):
+        response = self.response
+        data = IFRAME_TEXT % self.context.sockjs_server.sockjs_url
+        hsh = hashlib.md5(data).hexdigest()
+
+        #value = self.request.headers.get('If-None-Match')
+        value = self.request.environ.get('HTTP_IF_NONE_MATCH')
+        if value:
+            if value.find(hsh) != -1:
+                del response.headers['Content-Type']
+                self.set_status(304)
+                return response
+
+        response.content_type = 'text/html'
+        response.charset = 'UTF-8'
+        self.enable_cache()
+        self.set_header('Etag', hsh)
+        response.body = data
+        return response

ginsfsm/protocols/sockjs/server/c_transport_websocket.py

     Sockjs Websocket transport implementation
 """
 import logging
-import random
 
 from pyramid.view import view_config
 
 
 #----------------------------------------------------------------#
 #                   GWebsocket Views
-#                   /websocket
+#                   /*/*/websocket
 #----------------------------------------------------------------#
 @view_config(
     context=GWebsocket,
     name='',
     attr='execute',
-    #request_method='GET',
 )
 class WebsocketTransport(WebSocketHandler):
     name = 'websocket'
         return response
 
     def open(self, event):
-        # Stats
-
-        # Disable nagle
-        #if self.server.settings['disable_nagle']:
-        #    self.gsock.socket.setsockopt(
-        #        socket.SOL_TCP, socket.TCP_NODELAY, 1)
-
         # Handle session
         self.session = self.context.sockjs_server.create_session(
             self.sid,
                 self.session.on_messages((msg,))
         except Exception:
             logging.exception('ERROR WebSocket json_decode')
-
-            # Close session on exception
-            #self.session.close()
-
             # Close running connection
             self.gsock.mt_drop()
 
     def on_close(self, event):
         # Close session if websocket connection was closed
         if self.session is not None:
-            # Stats
-
             # Detach before closing session
             session = self.session
             self._detach()
 
 #----------------------------------------------------------------#
 #                   GRawWebsocket Views
-#                   /rawwebsocket
+#                   /websocket
 #----------------------------------------------------------------#
 @view_config(
     context=GRawWebsocket,
     name='',
     attr='execute',
-    #request_method='GET',
 )
 class RawWebsocketTransport(WebSocketHandler):
     name = 'rawwebsocket'
         self.session = None
         self.active = True
 
-    def get(self):
-        # session
-        response = self.response
-        session_id = self.sid = '%0.9d' % random.randint(1, 2147483647)
+    def execute(self):
+        self.sid = self.context.parent.re_matched_name
+        response = self._execute()
+        return response
 
-        manager = self.session_manager
-
-        sid = '%0.9d' % random.randint(1, 2147483647)
-        #if self.per_user:
-        #    sid = (authenticated_userid(request), sid)
-        """
-        session = manager.get(sid, True, request=request)
-        request.environ['wsgi.sockjs_session'] = session
-
-        # websocket
-        if 'HTTP_ORIGIN' in request.environ:
-            return HTTPNotFound()
-
-        res = init_websocket(request)
-        if res is not None:
-            return res
-
-        return RawWebSocketTransport(session, request)
-        """
-
-    def open(self):
-        # Stats
-
-        # Disable nagle if needed
-        #if self.server.settings['disable_nagle']:
-        #    self.gsock.socket.setsockopt(
-        #        socket.SOL_TCP, socket.TCP_NODELAY, 1)
-
+    def open(self, event):
         # Create and attach to session
         self.session = RawSession(
             self.server.get_connection_class(),
             self.session.remove_handler(self)
             self.session = None
 
-    def on_message(self, message):
+    def on_message(self, event):
+        message = event.data
         # SockJS requires that empty messages should be ignored
         if not message or not self.session:
             return
 
             # Close running connection
             self._detach()
-            self.abort_connection()
+            self.gsock.mt_drop()
 
-    def on_close(self):
+    def on_close(self, event):
         # Close session if websocket connection was closed
         if self.session is not None:
-            # Stats
-            self.server.stats.on_conn_closed()
-
+            # Detach before closing session
             session = self.session
             self._detach()
             session.close()
         try:
             self.write_message(message, binary)
         except IOError:
-            self.server.io_loop.add_callback(self.on_close)
+            self.context.sockjs_server.gaplic.add_callback(self.on_close)
 
     def session_closed(self):
+        # If session was closed by the application, terminate websocket
+        # connection as well.
         try:
             self.close()
         except IOError:

ginsfsm/protocols/sockjs/server/static.py

-# -*- encoding: utf-8 -*-
-""" basehandler
-"""
-
-import random
-import hashlib
-from sys import maxint
-
-from pyramid.view import view_config
-
-from ginsfsm.protocols.sockjs.server.protocol import json
-from ginsfsm.protocols.sockjs.server.basehandler import (
-    PreflightHandler,
-    BaseHandler,
-)
-from ginsfsm.gobj import GObj
-
-
-#----------------------------------------------------------------#
-#                   Info GClass
-#----------------------------------------------------------------#
-GINFO_GCONFIG = {
-    'sockjs_server': [None, None, 0, None, ""],
-}
-
-
-class GInfo(GObj):
-    """  GInfo GObj.
-    """
-    def __init__(self):
-        GObj.__init__(self, {}, GINFO_GCONFIG)
-
-    def start_up(self):
-        """ Initialization zone.
-        """
-        # Info Test views
-        """
-        self.sockjs_server.pyramid_config.add_view(
-            context=GInfo,
-            name='',
-            view=InfoHandler,
-            attr='get',
-            path_info=self.resource_path(),
-            request_method='GET',
-            permission=self.sockjs_server.permission,
-        )
-        self.sockjs_server.pyramid_config.add_view(
-            context=GInfo,
-            name='',
-            view=InfoHandler,
-            attr='options',
-            path_info=self.resource_path(),
-            request_method='OPTIONS',
-            permission=self.sockjs_server.permission,
-        )
-        """
-
-
-#----------------------------------------------------------------#
-#                   Info views
-#----------------------------------------------------------------#
-@view_config(
-    context=GInfo,
-    name='',
-    attr='get',
-    request_method='GET',
-)
-@view_config(
-    context=GInfo,
-    name='',
-    attr='options',
-    request_method='OPTIONS',
-)
-class InfoHandler(PreflightHandler):
-    """SockJS 0.2+ /info handler"""
-    def __init__(self, context, request):
-        PreflightHandler.__init__(self, context, request)
-        self.access_methods = 'OPTIONS, GET'
-
-    def get(self):
-        response = self.response
-        response.content_type = 'application/json'
-        response.charset = 'UTF-8'
-        self.preflight()
-        self.disable_cache()
-
-        info = {
-            'websocket':
-                'websocket' not in self.context.sockjs_server.disabled_transports,
-            'cookie_needed': self.context.sockjs_server.cookie_needed,
-            'origins': ['*:*'],
-            'entropy': random.randint(0, maxint),
-        }
-        response.body = json.dumps(info)
-        return response
-
-
-#----------------------------------------------------------------#
-#                   IFrame GClass
-#----------------------------------------------------------------#
-GIFRAME_GCONFIG = {
-    'sockjs_server': [None, None, 0, None, ""],
-}
-
-
-class GIFrame(GObj):
-    """  GIFrame GObj.
-    """
-    def __init__(self):
-        GObj.__init__(self, {}, GIFRAME_GCONFIG)
-
-    def start_up(self):
-        """ Initialization zone.
-        """
-        """
-        self.sockjs_server.pyramid_config.add_view(
-            context=GIFrame,
-#            name='',
-            view=IFrameHandler,
-            attr='get',
-            path_info=self.resource_path(),
-            request_method='GET',
-            permission=self.sockjs_server.permission,
-        )
-        """
-
-#----------------------------------------------------------------#
-#                   IFrame views
-#----------------------------------------------------------------#
-IFRAME_TEXT = """<!DOCTYPE html>
-<html>
-<head>
-  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
-  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
-  <script>
-    document.domain = document.domain;
-    _sockjs_onload = function(){SockJS.bootstrap_iframe();};
-  </script>
-  <script src="%s"></script>
-</head>
-<body>
-  <h2>Don't panic!</h2>
-  <p>This is a SockJS hidden iframe. It's used for cross domain magic.</p>
-</body>
-</html>
-""".strip()
-
-
-@view_config(
-    context=GIFrame,
-    name='',
-    attr='get',
-    request_method='GET',
-)
-class IFrameHandler(BaseHandler):
-    """SockJS IFrame page handler"""
-    def get(self):
-        response = self.response
-        data = IFRAME_TEXT % self.context.sockjs_server.sockjs_url
-        hsh = hashlib.md5(data).hexdigest()
-
-        #value = self.request.headers.get('If-None-Match')
-        value = self.request.environ.get('HTTP_IF_NONE_MATCH')
-        if value:
-            if value.find(hsh) != -1:
-                del response.headers['Content-Type']
-                self.set_status(304)
-                return response
-
-        response.content_type = 'text/html'
-        response.charset = 'UTF-8'
-        self.enable_cache()
-        self.set_header('Etag', hsh)
-        response.body = data
-        return response