chatserver.xml 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <class name="ChatServer">
  2. <relationships>
  3. <association name="server" class="NetworkServer"/>
  4. </relationships>
  5. <constructor>
  6. <parameter name="port"/>
  7. <body>
  8. <![CDATA[
  9. self.room2clients = {}
  10. self.client2room = {}
  11. self.serverinstance = None
  12. self.queue = []
  13. self.port = port
  14. self.tmp_sendlist = []
  15. self.tmp_data = None
  16. ]]>
  17. </body>
  18. </constructor>
  19. <scxml>
  20. <parallel id="server">
  21. <state id="processor" initial="init">
  22. <state id="init">
  23. <onentry>
  24. <raise scope="cd" event="create_instance">
  25. <parameter expr="'server'"/>
  26. <parameter expr="'NetworkServer'"/>
  27. <parameter expr="self.port"/>
  28. </raise>
  29. </onentry>
  30. <transition event="instance_created" target="../main">
  31. <parameter name="instancename"/>
  32. <script>
  33. self.serverinstance = instancename
  34. </script>
  35. <raise scope="narrow" event="set_association_name" target="instancename">
  36. <parameter expr="instancename"/>
  37. </raise>
  38. <raise scope="cd" event="start_instance">
  39. <parameter expr="instancename"/>
  40. </raise>
  41. </transition>
  42. </state>
  43. <state id="main">
  44. <transition cond="len(self.queue) > 0 and self.queue[0][1].startswith('ACK ')" target="."/>
  45. <transition cond="len(self.queue) > 0 and self.queue[0][1].startswith('MSG ')" target="../forwarding">
  46. <script>
  47. socket, data = self.queue.pop(0)
  48. roomnumber = self.client2room[socket]
  49. self.tmp_sendlist = set(self.room2clients[roomnumber])
  50. # Don't send to the original sender
  51. # This also prevents infinite propagation to the other server
  52. self.tmp_sendlist.remove(socket)
  53. self.tmp_sendlist = list(self.tmp_sendlist)
  54. self.tmp_data = data
  55. </script>
  56. <raise scope="broad" event="server_input">
  57. <parameter expr="socket"/>
  58. <parameter expr="'ACK MSG'"/>
  59. </raise>
  60. </transition>
  61. <transition cond="len(self.queue) > 0 and self.queue[0][1].startswith('POLL')" target=".">
  62. <script>
  63. socket, data = self.queue.pop(0)
  64. </script>
  65. <raise scope="broad" event="server_input">
  66. <parameter expr="socket"/>
  67. <parameter expr="'ALIVE'"/>
  68. </raise>
  69. </transition>
  70. <transition cond="len(self.queue) > 0 and self.queue[0][1].startswith('JOIN ')" target=".">
  71. <script>
  72. socket, data = self.queue.pop(0)
  73. roomnumber = int(data[5:])
  74. self.room2clients.setdefault(roomnumber, set()).add(socket)
  75. self.client2room[socket] = roomnumber
  76. </script>
  77. <raise scope="broad" event="server_input">
  78. <parameter expr="socket"/>
  79. <parameter expr="'ACK JOIN %i' % roomnumber"/>
  80. </raise>
  81. </transition>
  82. <transition cond="len(self.queue) > 0 and self.queue[0][1].startswith('LEAVE')" target=".">
  83. <script>
  84. socket, data = self.queue.pop(0)
  85. roomnumber = self.client2room[socket]
  86. self.room2clients[roomnumber].remove(socket)
  87. del self.client2room[socket]
  88. </script>
  89. <raise scope="broad" event="server_input">
  90. <parameter expr="socket"/>
  91. <parameter expr="'ACK LEAVE'"/>
  92. </raise>
  93. </transition>
  94. </state>
  95. <state id="forwarding">
  96. <transition cond="len(self.tmp_sendlist) > 0" target=".">
  97. <raise scope="broad" event="server_input">
  98. <parameter expr="self.tmp_sendlist.pop()"/>
  99. <parameter expr="self.tmp_data"/>
  100. </raise>
  101. </transition>
  102. <transition cond="len(self.tmp_sendlist) == 0" target="../main"/>
  103. </state>
  104. </state>
  105. <state id="receiver">
  106. <state id="queue">
  107. <transition event="server_output" target=".">
  108. <parameter name="socket"/>
  109. <parameter name="data"/>
  110. <script>
  111. self.queue.append((socket, data))
  112. </script>
  113. </transition>
  114. </state>
  115. </state>
  116. </parallel>
  117. </scxml>
  118. </class>