server.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import socket
  2. import logging
  3. from traceback import format_exc
  4. from websocket import WebSocket
  5. class Server(object):
  6. def __init__(self, port, address='', log_level=logging.INFO, protocols=[],
  7. encoding=None):
  8. logging.basicConfig(level=log_level,
  9. format='%(asctime)s: %(levelname)s: %(message)s',
  10. datefmt='%H:%M:%S')
  11. self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  12. self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  13. logging.info('Starting server at %s:%d', address, port)
  14. self.sock.bind((address, port))
  15. self.sock.listen(5)
  16. self.clients = []
  17. self.protocols = protocols
  18. self.encoding = encoding
  19. def run(self):
  20. while True:
  21. try:
  22. client_socket, address = self.sock.accept()
  23. logging.debug('Attempting handshake with %s:%d' % address)
  24. self.handshake(client_socket)
  25. client = Client(self, client_socket, address)
  26. self.clients.append(client)
  27. logging.info('Registered client %s', client)
  28. self.onopen(client)
  29. client.run_threaded()
  30. except KeyboardInterrupt:
  31. logging.info('Received interrupt, stopping server...')
  32. break
  33. except Exception as e:
  34. logging.error(format_exc(e))
  35. def onopen(self, client):
  36. """
  37. Called when a new client connects.
  38. """
  39. pass
  40. def onmessage(self, client, message):
  41. """
  42. Called when a message is received from some client. `message' is a
  43. Message object
  44. """
  45. raise NotImplemented
  46. def onclose(self, client):
  47. """
  48. Called when a client disconnects.
  49. """
  50. pass
  51. class Client(WebSocket):
  52. def __init__(self, server, sock, address):
  53. super(Client, self).__init__(sock, address)
  54. self.server = server
  55. def onopen(self):
  56. self.server.onopen(self)
  57. def onmessage(self, message):
  58. self.server.onmessage(self, message)
  59. def onclose(self):
  60. self.server.onclose(self, message)
  61. def __str__(self):
  62. return '<Client at %s:%d>' % self.address
  63. if __name__ == '__main__':
  64. import sys
  65. port = int(sys.argv[1]) if len(sys.argv) > 1 else 80
  66. Server(port=port, log_level=logging.DEBUG, encoding='utf-8').run()