| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- <class name="ChatServer">
- <relationships>
- <association name="server" class="NetworkServer"/>
- </relationships>
- <constructor>
- <parameter name="port"/>
- <body>
- <![CDATA[
- self.room2clients = {}
- self.client2room = {}
- self.serverinstance = None
- self.queue = []
- self.port = port
- self.tmp_sendlist = []
- self.tmp_data = None
- ]]>
- </body>
- </constructor>
- <scxml>
- <parallel id="server">
- <state id="processor" initial="init">
- <state id="init">
- <onentry>
- <raise scope="cd" event="create_instance">
- <parameter expr="'server'"/>
- <parameter expr="'NetworkServer'"/>
- <parameter expr="self.port"/>
- </raise>
- </onentry>
- <transition event="instance_created" target="../main">
- <parameter name="instancename"/>
- <script>
- self.serverinstance = instancename
- </script>
- <raise scope="narrow" event="set_association_name" target="instancename">
- <parameter expr="instancename"/>
- </raise>
- <raise scope="cd" event="start_instance">
- <parameter expr="instancename"/>
- </raise>
- </transition>
- </state>
- <state id="main">
- <transition cond="len(self.queue) > 0 and self.queue[0][1].startswith('ACK ')" target="."/>
- <transition cond="len(self.queue) > 0 and self.queue[0][1].startswith('MSG ')" target="../forwarding">
- <script>
- socket, data = self.queue.pop(0)
- roomnumber = self.client2room[socket]
- self.tmp_sendlist = set(self.room2clients[roomnumber])
- # Don't send to the original sender
- # This also prevents infinite propagation to the other server
- self.tmp_sendlist.remove(socket)
- self.tmp_sendlist = list(self.tmp_sendlist)
- self.tmp_data = data
- </script>
- <raise scope="broad" event="server_input">
- <parameter expr="socket"/>
- <parameter expr="'ACK MSG'"/>
- </raise>
- </transition>
- <transition cond="len(self.queue) > 0 and self.queue[0][1].startswith('POLL')" target=".">
- <script>
- socket, data = self.queue.pop(0)
- </script>
- <raise scope="broad" event="server_input">
- <parameter expr="socket"/>
- <parameter expr="'ALIVE'"/>
- </raise>
- </transition>
- <transition cond="len(self.queue) > 0 and self.queue[0][1].startswith('JOIN ')" target=".">
- <script>
- socket, data = self.queue.pop(0)
- roomnumber = int(data[5:])
- self.room2clients.setdefault(roomnumber, set()).add(socket)
- self.client2room[socket] = roomnumber
- </script>
- <raise scope="broad" event="server_input">
- <parameter expr="socket"/>
- <parameter expr="'ACK JOIN %i' % roomnumber"/>
- </raise>
- </transition>
- <transition cond="len(self.queue) > 0 and self.queue[0][1].startswith('LEAVE')" target=".">
- <script>
- socket, data = self.queue.pop(0)
- roomnumber = self.client2room[socket]
- self.room2clients[roomnumber].remove(socket)
- del self.client2room[socket]
- </script>
- <raise scope="broad" event="server_input">
- <parameter expr="socket"/>
- <parameter expr="'ACK LEAVE'"/>
- </raise>
- </transition>
- </state>
- <state id="forwarding">
- <transition cond="len(self.tmp_sendlist) > 0" target=".">
- <raise scope="broad" event="server_input">
- <parameter expr="self.tmp_sendlist.pop()"/>
- <parameter expr="self.tmp_data"/>
- </raise>
- </transition>
- <transition cond="len(self.tmp_sendlist) == 0" target="../main"/>
- </state>
- </state>
- <state id="receiver">
- <state id="queue">
- <transition event="server_output" target=".">
- <parameter name="socket"/>
- <parameter name="data"/>
- <script>
- self.queue.append((socket, data))
- </script>
- </transition>
- </state>
- </state>
- </parallel>
- </scxml>
- </class>
|