1 """This is a websocket chat example with many servers. A client can connect to
2 any of the servers and their messages will be received by all clients connected
5 Run the examples like this:
7 $ python examples/chat_bridge.py tcp://127.0.0.1:12345 tcp://127.0.0.1:12346
9 and the servers like this (changing the port for each one obviously):
11 $ python examples/distributed_websocket_chat.py -p tcp://127.0.0.1:12345 -s tcp://127.0.0.1:12346 7000
13 So all messages are published to port 12345 and the device forwards all the
14 messages to 12346 where they are subscribed to
19 from collections import defaultdict
20 from eventlet import spawn_n, sleep
21 from eventlet import wsgi
22 from eventlet import websocket
23 from eventlet.green import zmq
24 from eventlet.hubs import get_hub, use_hub
25 from uuid import uuid1
43 def pack_message(self, msg):
46 def unpack_message(self, msg):
48 sender_name = 'you said' if sender.id == self.id \
49 else '%s says' % sender
50 return "%s: %s" % (sender_name, message)
53 participants = defaultdict(IDName)
56 def subscribe_and_distribute(sub_socket):
59 msg = sub_socket.recv_pyobj()
60 for ws, name_id in participants.items():
61 to_send = name_id.unpack_message(msg)
69 @websocket.WebSocketWSGI
72 name_id = participants[ws]
73 ws.send("Connected as %s, change name with 'name: new_name'" % name_id)
79 if m.startswith('name:'):
80 old_name = str(name_id)
81 new_name = m.split(':', 1)[1].strip()
82 name_id.name = new_name
83 m = 'Changed name from %s' % old_name
84 pub_socket.send_pyobj(name_id.pack_message(m))
90 def dispatch(environ, start_response):
91 """Resolves to the web page or the websocket depending on the path."""
93 if environ['PATH_INFO'] == '/chat':
94 return handle(environ, start_response)
96 start_response('200 OK', [('content-type', 'text/html')])
97 return [open(os.path.join(
98 os.path.dirname(__file__),
99 'websocket_chat.html')).read() % dict(port=port)]
103 if __name__ == "__main__":
104 usage = 'usage: websocket_chat -p pub address -s sub address port number'
105 if len(sys.argv) != 6:
109 pub_addr = sys.argv[2]
110 sub_addr = sys.argv[4]
112 port = int(sys.argv[5])
114 print("Error port supplied couldn't be converted to int\n", usage)
118 pub_socket = ctx.socket(zmq.PUB)
119 pub_socket.connect(pub_addr)
120 print("Publishing to %s" % pub_addr)
121 sub_socket = ctx.socket(zmq.SUB)
122 sub_socket.connect(sub_addr)
123 sub_socket.setsockopt(zmq.SUBSCRIBE, "")
124 print("Subscribing to %s" % sub_addr)
126 print("Couldn't create sockets\n", usage)
129 spawn_n(subscribe_and_distribute, sub_socket)
130 listener = eventlet.listen(('127.0.0.1', port))
131 print("\nVisit http://localhost:%s/ in your websocket-capable browser.\n" % port)
132 wsgi.server(listener, dispatch)