|
2 | 2 | import logging
|
3 | 3 |
|
4 | 4 | from bidict import bidict, ValueDuplicationError
|
| 5 | +from engineio import packet as eio_packet |
| 6 | +from socketio import packet |
5 | 7 |
|
6 | 8 | default_logger = logging.getLogger('socketio')
|
7 | 9 |
|
@@ -161,15 +163,42 @@ def emit(self, event, data, namespace, room=None, skip_sid=None,
|
161 | 163 | connected to the namespace."""
|
162 | 164 | if namespace not in self.rooms:
|
163 | 165 | return
|
| 166 | + if isinstance(data, tuple): |
| 167 | + # tuples are expanded to multiple arguments, everything else is |
| 168 | + # sent as a single argument |
| 169 | + data = list(data) |
| 170 | + elif data is not None: |
| 171 | + data = [data] |
| 172 | + else: |
| 173 | + data = [] |
164 | 174 | if not isinstance(skip_sid, list):
|
165 | 175 | skip_sid = [skip_sid]
|
166 |
| - for sid, eio_sid in self.get_participants(namespace, room): |
167 |
| - if sid not in skip_sid: |
168 |
| - if callback is not None: |
| 176 | + if not callback: |
| 177 | + # when callbacks aren't used the packets sent to each recipient are |
| 178 | + # identical, so they can be generated once and reused |
| 179 | + pkt = self.server.packet_class( |
| 180 | + packet.EVENT, namespace=namespace, data=[event] + data) |
| 181 | + encoded_packet = pkt.encode() |
| 182 | + if not isinstance(encoded_packet, list): |
| 183 | + encoded_packet = [encoded_packet] |
| 184 | + eio_pkt = [eio_packet.Packet(eio_packet.MESSAGE, p) |
| 185 | + for p in encoded_packet] |
| 186 | + for sid, eio_sid in self.get_participants(namespace, room): |
| 187 | + if sid not in skip_sid: |
| 188 | + for p in eio_pkt: |
| 189 | + self.server._send_eio_packet(eio_sid, p) |
| 190 | + else: |
| 191 | + # callbacks are used, so each recipient must be sent a packet that |
| 192 | + # contains a unique callback id |
| 193 | + # note that callbacks when addressing a group of people are |
| 194 | + # implemented but not tested or supported |
| 195 | + for sid, eio_sid in self.get_participants(namespace, room): |
| 196 | + if sid not in skip_sid: # pragma: no branch |
169 | 197 | id = self._generate_ack_id(sid, callback)
|
170 |
| - else: |
171 |
| - id = None |
172 |
| - self.server._emit_internal(eio_sid, event, data, namespace, id) |
| 198 | + pkt = self.server.packet_class( |
| 199 | + packet.EVENT, namespace=namespace, data=[event] + data, |
| 200 | + id=id) |
| 201 | + self.server._send_packet(eio_sid, pkt) |
173 | 202 |
|
174 | 203 | def trigger_callback(self, sid, id, data):
|
175 | 204 | """Invoke an application callback."""
|
|
0 commit comments