publish.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. from . import schedule_coroutine
  2. # =============================================================================
  3. # singleton publish manager
  4. class PublishManager(object):
  5. def __init__(self):
  6. self.protocols = []
  7. self.attachmentMap = {}
  8. self.attachmentRefCounts = {} # keyed same as attachment map
  9. self.attachmentId = 0
  10. self.publishCount = 0
  11. def registerProtocol(self, protocol):
  12. self.protocols.append(protocol)
  13. def unregisterProtocol(self, protocol):
  14. if protocol in self.protocols:
  15. self.protocols.remove(protocol)
  16. def getAttachmentMap(self):
  17. return self.attachmentMap
  18. def clearAttachmentMap(self):
  19. self.attachmentMap.clear()
  20. def registerAttachment(self, attachKey):
  21. self.attachmentRefCounts[attachKey] += 1
  22. def unregisterAttachment(self, attachKey):
  23. self.attachmentRefCounts[attachKey] -= 1
  24. def freeAttachments(self, keys=None):
  25. keys_to_delete = []
  26. keys_to_check = keys if keys is not None else [k for k in self.attachmentMap]
  27. for key in keys_to_check:
  28. if self.attachmentRefCounts.get(key) == 0:
  29. keys_to_delete.append(key)
  30. for key in keys_to_delete:
  31. self.attachmentMap.pop(key)
  32. self.attachmentRefCounts.pop(key)
  33. def addAttachment(self, payload):
  34. # print("attachment", self, self.attachmentId)
  35. # use a string flag in place of the binary attachment.
  36. binaryId = "wslink_bin{0}".format(self.attachmentId)
  37. self.attachmentMap[binaryId] = payload
  38. self.attachmentRefCounts[binaryId] = 0
  39. self.attachmentId += 1
  40. return binaryId
  41. def publish(self, topic, data, client_id=None, skip_last_active_client=False):
  42. for protocol in self.protocols:
  43. # The client is unknown - we send to any client who is subscribed to the topic
  44. rpcid = "publish:{0}:{1}".format(topic, self.publishCount)
  45. schedule_coroutine(
  46. 0,
  47. protocol.sendWrappedMessage,
  48. rpcid,
  49. data,
  50. client_id=client_id,
  51. skip_last_active_client=skip_last_active_client,
  52. )
  53. # singleton, used by all instances of WslinkWebSocketServerProtocol
  54. publishManager = PublishManager()
  55. # from http://www.jsonrpc.org/specification, section 5.1
  56. METHOD_NOT_FOUND = -32601
  57. AUTHENTICATION_ERROR = -32000
  58. EXCEPTION_ERROR = -32001
  59. RESULT_SERIALIZE_ERROR = -32002
  60. # used in client JS code:
  61. CLIENT_ERROR = -32099