Created
September 30, 2010 04:55
-
-
Save commandodev/604047 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
from zmq import FORWARDER, PUB, SUB, SUBSCRIBE | |
from zmq.devices import Device | |
if __name__ == "__main__": | |
usage = 'usage: chat_bridge pub_address sub_address' | |
if len (sys.argv) != 3: | |
print usage | |
sys.exit(1) | |
pub_addr = sys.argv[1] | |
sub_addr = sys.argv[2] | |
print "Recieving on %s" % sub_addr | |
print "Sending on %s" % pub_addr | |
device = Device(FORWARDER, SUB, PUB) | |
device.bind_in(sub_addr) | |
device.setsockopt_in(SUBSCRIBE, "") | |
device.bind_out(pub_addr) | |
device.start() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""This is a websocket chat example with many servers. A client can connect to | |
any of the servers and their messages will be received by all clients connected | |
to any of the servers. | |
Run the examples like this: | |
$ python examples/chat_bridge.py tcp://127.0.0.1:12345 tcp://127.0.0.1:12346 | |
and the servers like this (changing the port for each one obviously): | |
$ python examples/distributed_websocket_chat.py -p tcp://127.0.0.1:12345 -s tcp://127.0.0.1:12346 7000 | |
So all messages are published to port 12345 and the device forwards all the | |
messages to 12346 where they are subscribed to | |
It requires this https://bitbucket.org/boothead/eventlet version of eventlet (for now), and a working zeromq/pyzmq install | |
""" | |
import os, sys | |
import eventlet | |
from collections import defaultdict | |
from eventlet import spawn_n, sleep | |
from eventlet import wsgi | |
from eventlet import websocket | |
from eventlet.green import zmq | |
from eventlet.hubs import get_hub, use_hub | |
from uuid import uuid1 | |
use_hub('zeromq') | |
hub = get_hub() | |
ctx = hub.get_context() | |
class IDName(object): | |
def __init__(self): | |
self.id = uuid1() | |
self.name = None | |
def __str__(self): | |
if self.name: | |
return self.name | |
else: | |
return str(self.id) | |
def pack_message(self, msg): | |
return self, msg | |
def unpack_message(self, msg): | |
sender, message = msg | |
sender_name = 'you said' if sender.id == self.id \ | |
else '%s says' % sender | |
return "%s: %s" % (sender_name, message) | |
participants = defaultdict(IDName) | |
def subscribe_and_distribute(sub_socket): | |
global participants | |
while True: | |
msg = sub_socket.recv_pyobj() | |
for ws, name_id in participants.items(): | |
to_send = name_id.unpack_message(msg) | |
if to_send: | |
try: | |
ws.send(to_send) | |
except: | |
del participants[ws] | |
@websocket.WebSocketWSGI | |
def handle(ws): | |
global pub_socket | |
name_id = participants[ws] | |
ws.send("Connected as %s, change name with 'name: new_name'" % name_id) | |
try: | |
while True: | |
m = ws.wait() | |
if m is None: | |
break | |
if m.startswith('name:'): | |
old_name = str(name_id) | |
new_name = m.split(':', 1)[1].strip() | |
name_id.name = new_name | |
m = 'Changed name from %s' % old_name | |
pub_socket.send_pyobj(name_id.pack_message(m)) | |
sleep() | |
finally: | |
del participants[ws] | |
def dispatch(environ, start_response): | |
"""Resolves to the web page or the websocket depending on the path.""" | |
global port | |
if environ['PATH_INFO'] == '/chat': | |
return handle(environ, start_response) | |
else: | |
start_response('200 OK', [('content-type', 'text/html')]) | |
return [open(os.path.join( | |
os.path.dirname(__file__), | |
'websocket_chat.html')).read() % dict(port=port)] | |
port = None | |
if __name__ == "__main__": | |
usage = 'usage: websocket_chat -p pub address -s sub address port number' | |
if len (sys.argv) != 6: | |
print usage | |
sys.exit(1) | |
pub_addr = sys.argv[2] | |
sub_addr = sys.argv[4] | |
try: | |
port = int(sys.argv[5]) | |
except ValueError: | |
print "Error port supplied couldn't be converted to int\n", usage | |
sys.exit(1) | |
try: | |
pub_socket = ctx.socket(zmq.PUB) | |
pub_socket.connect(pub_addr) | |
print "Publishing to %s" % pub_addr | |
sub_socket = ctx.socket(zmq.SUB) | |
sub_socket.connect(sub_addr) | |
sub_socket.setsockopt(zmq.SUBSCRIBE, "") | |
print "Subscribing to %s" % sub_addr | |
except: | |
print "Couldn't create sockets\n", usage | |
sys.exit(1) | |
spawn_n(subscribe_and_distribute, sub_socket) | |
listener = eventlet.listen(('127.0.0.1', port)) | |
print "\nVisit http://localhost:%s/ in your websocket-capable browser.\n" % port | |
wsgi.server(listener, dispatch) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment