resource.py 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import re
  2. from .protocols.base import BaseProtocol
  3. from .exceptions import WebSocketError
  4. class WebSocketApplication(object):
  5. protocol_class = BaseProtocol
  6. def __init__(self, ws):
  7. self.protocol = self.protocol_class(self)
  8. self.ws = ws
  9. def handle(self):
  10. self.protocol.on_open()
  11. while True:
  12. try:
  13. message = self.ws.receive()
  14. except WebSocketError:
  15. self.protocol.on_close()
  16. break
  17. self.protocol.on_message(message)
  18. def on_open(self, *args, **kwargs):
  19. pass
  20. def on_close(self, *args, **kwargs):
  21. pass
  22. def on_message(self, message, *args, **kwargs):
  23. self.ws.send(message, **kwargs)
  24. @classmethod
  25. def protocol_name(cls):
  26. return cls.protocol_class.PROTOCOL_NAME
  27. class Resource(object):
  28. def __init__(self, apps=None):
  29. self.apps = apps if apps else []
  30. def _app_by_path(self, environ_path):
  31. # Which app matched the current path?
  32. for path, app in self.apps.iteritems():
  33. if re.match(path, environ_path):
  34. return app
  35. def app_protocol(self, path):
  36. app = self._app_by_path(path)
  37. if hasattr(app, 'protocol_name'):
  38. return app.protocol_name()
  39. else:
  40. return ''
  41. def __call__(self, environ, start_response):
  42. environ = environ
  43. current_app = self._app_by_path(environ['PATH_INFO'])
  44. if current_app is None:
  45. raise Exception("No apps defined")
  46. if 'wsgi.websocket' in environ:
  47. ws = environ['wsgi.websocket']
  48. current_app = current_app(ws)
  49. current_app.ws = ws # TODO: needed?
  50. current_app.handle()
  51. return None
  52. else:
  53. return current_app(environ, start_response)