def __init__(self, remote_host, port, zmq_factory, data_manager=None): self.data_manager = data_manager self.remote_host = remote_host self.generation_signal_listeners = [] endpoint = ZmqEndpoint(ZmqEndpointType.connect, "tcp://%s:%d" % (remote_host, port)) ZmqSubConnection.__init__(self, zmq_factory, endpoint)
def on_msg(self, callBack, time_out = None): """ A messy callback handler for when a new message pops up. :param callBack: expected def callBack(stringMessage) :param time_out: TODO a timeout value in seconds """ """ This is a tad not production sane as its going to open a new ZMQ socket for every single message sent. Its fine when it's just 1-2 people chatting for a short-demo duration but a better approach might be to bind the client ZMQ socket to a HTTP session with a timeout. So say someone leaves, the HTTP session would timeout after some T duration and this socket would be cleaned up. Additionally this would prevent some amount of thrash of instantiating and destroying sockets. """ client = ZmqSubConnection(self.zf, self.client) client.subscribe("") self.clients.append(client) print len(self.clients), " waiting clients" def cleanup(): """ Our message is done, clean up! """ c_index = self.clients.index(client) self.clients.pop(c_index) client.shutdown() def on_msg(*args, **kwargs): try: callBack("".join(args[:-1])) finally: cleanup() """ Blink and you might miss it, this does the actual binding to the client socket. Initially I thought "Man this would be some much better using a deferred" EXCEPT what happens after that first deferred fires? """ client.gotMessage = on_msg
def main(): parser = OptionParser("") parser.add_option("-m", "--method", dest="method", help="0MQ socket connection: bind|connect") parser.add_option("-e", "--endpoint", dest="endpoint", help="0MQ Endpoint") parser.set_defaults(method="connect", endpoint="tcp://localhost:5555") (options, args) = parser.parse_args() zf = ZmqFactory() e = ZmqEndpoint(options.method, options.endpoint) s = ZmqSubConnection(zf, e) s.subscribe("") def doPrint(*args): print "message received: %r" % (args, ) s.gotMessage = doPrint reactor.run()
def __init__(self, controller): self.controller = controller self.event_handlers = [] self.event_interfaces = {} try: config = self.controller.config_file.items('router') except NoSectionError: config = {} zmq_factory = ZmqFactory() pub_endpoint = ZmqEndpoint('connect', config.get('pub-endpoint', DEFAULT_PUB_ENDPOINT)) self.zmq_sub = ZmqSubConnection(zmq_factory, pub_endpoint) self.zmq_sub.subscribe('') self.zmq_sub.gotMessage = self.process_message
def main(): global _CONFIG with open('config.yml') as f: _CONFIG = yaml.load(f.read()) log.startLogging(sys.stderr) ircf = IrcFactory() reactor.connectTCP(_CONFIG['host'], _CONFIG['port'], ircf) zf = ZmqFactory() e = ZmqEndpoint(_CONFIG['method'], _CONFIG['endpoint']) s = ZmqSubConnection(zf, e) s.subscribe("") def do_forward(*args): if _IRC_PROTOCOL: _IRC_PROTOCOL.forward(json.loads(args[0])) s.gotMessage = do_forward reactor.run()
(options, args) = parser.parse_args() zf = ZmqFactory() def bind_or_connect(s): if options.method == 'bind': s.bind(options.endpoint) elif options.method == 'connect': s.connect(options.endpoint) if options.mode == "publisher": pub = ZmqPubConnection(zf) bind_or_connect(pub) def publish(): data = str(time.time()) print "publishing %r" % data pub.send(data) reactor.callLater(1, publish) publish() else: def doPrint(msgs): print "message received: %r" % (msgs, ) sub = ZmqSubConnection(zf, callback=doPrint) sub.setsockopt(zmq.SUBSCRIBE, '') bind_or_connect(sub) reactor.run()
def shutdown(self): self.unsubscribe("GENSIG") ZmqSubConnection.shutdown(self)
class EventManager(object): def __init__(self, controller): self.controller = controller self.event_handlers = [] self.event_interfaces = {} try: config = self.controller.config_file.items('router') except NoSectionError: config = {} zmq_factory = ZmqFactory() pub_endpoint = ZmqEndpoint('connect', config.get('pub-endpoint', DEFAULT_PUB_ENDPOINT)) self.zmq_sub = ZmqSubConnection(zmq_factory, pub_endpoint) self.zmq_sub.subscribe('') self.zmq_sub.gotMessage = self.process_message def register_event_handler(self, handler): for event_interface in zope.interface.providedBy(handler): if event_interface.extends(IAutomatronEventHandler): event_interface_name = event_interface.getName() if event_interface_name in self.event_interfaces: if self.event_interfaces[event_interface_name] is not event_interface: log.msg('Warning: Duplicate event handler interface name: %s' % event_interface_name) else: self.event_interfaces[event_interface_name] = event_interface try: zope.interface.verify.verifyObject(event_interface, handler) except (zope.interface.verify.BrokenImplementation, zope.interface.verify.BrokenMethodImplementation) as e: log.err(e, 'Event handler %s is broken' % handler.name) break else: self.event_handlers.append(handler) log.msg('Loaded event handler %s' % handler.name) @defer.inlineCallbacks def dispatch_event(self, interface_event_name, *args): interface_name, event_name = interface_event_name.split('.', 1) if not interface_name in self.event_interfaces: return event_interface = self.event_interfaces[interface_name] event = event_interface[event_name] if not event_interface.extends(IAutomatronEventHandler): log.msg('Emitted event %s\'s interface (%s) does not extend IAutomatronEventHandler' % (event_name, interface_event_name)) return if len(args) < len(event.required): log.msg('Emitted event %s\'s declaration requires at least %d arguments, only %d were ' 'provided.' % (interface_event_name, len(event.required), len(args))) return if len(args) > len(event.positional): log.msg('Emitted event %s\'s declaration requires at most %d arguments, %d were ' 'provided.' % (interface_event_name, len(event.positional), len(args))) return event_handlers = sorted(self.event_handlers, key=lambda i: i.priority) for plugin in event_handlers: try: event_handler_adapter = event_interface(plugin) except TypeError: continue f = getattr(event_handler_adapter, event.getName()) if (yield defer.maybeDeferred(f, *args)) is STOP: defer.returnValue(STOP) def process_message(self, message, tag): args = cPickle.loads(message) self.dispatch_event(tag, *args)
from rpi.config import ZMQ_PORT, local_configs ## publisher _context = zmq.Context() _pub_socket = _context.socket(zmq.PUB) _pub_socket.bind("tcp://*:{}".format(ZMQ_PORT)) def zmq_publish(msg): print('publishing "{}" to peers via 0mq'.format(msg)) _pub_socket.send(msg) ###### subscriber, for twisted ###### zf = ZmqFactory() subscriber = ZmqSubConnection(zf) def _create_endpoint(treename): return ZmqEndpoint("connect", "tcp://{}:{}".format( local_configs['other_trees'][treename], ZMQ_PORT)) _endpoints = [_create_endpoint(treename) for treename in local_configs['connect_to']] subscriber.addEndpoints(_endpoints) # in `main.py`, specific behavior is configured, such as: # subscriber.subscribe("othertreename") # subscriber.gotMessage = handle_incoming_zmq_msg
class RadClientWorker(object): def __init__(self, gdata): self.gdata = gdata self.config = gdata.config self.que = deque() self.cache = gdata.cache self.db_engine = gdata.db_engine self.metadata = models.get_metadata(self.db_engine) self.ops = { 'radstart':self.start_session, 'radstop':self.stop_session } self.radstart = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('connect', self.config.mqproxy.radstart_connect)) self.radstop = ZmqSubConnection(ZmqFactory(), ZmqEndpoint('connect',self.config.mqproxy.radstop_connect)) self.radresp = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', self.config.mqproxy.radresp_connect)) self.radstop.subscribe('radstop') self.radstop.gotMessage = self.subdataReceived self.radstart.onPull = self.dataReceived self.process_poll() logger.info("Start radstart %s" % self.radstart) logger.info("Start radstop %s" % self.radstop) logger.info("Start radresp %s" % self.radresp) def subdataReceived(self, request,tag): try: message = msgpack.unpackb(request) if self.config.system.debug: logger.debug(u"received radius start request:"+utils.safeunicode(message)) self.que.appendleft(message) except: traceback.print_exc() def dataReceived(self, request): try: message = msgpack.unpackb(request[0]) if self.config.system.debug: logger.debug(u"received radius start request:"+utils.safeunicode(message)) self.que.appendleft(message) except: traceback.print_exc() def start_session(self,userdata): username = userdata['username'] password = userdata['password'] radius_ipaddr = userdata['radius_ipaddr'] num = userdata.get("num",1) isresp = int(userdata.get("isresp",0)) sendresp = lambda r : self.radresp.push(msgpack.packb(['radstart_resp',r])) if isresp else None senderror = lambda e: self.radresp.push(msgpack.packb(['radstart_error',dict(code=1,msg=repr(e))])) if isresp else None for i in range(num): rad_session = RadiusSession(self.config,self.db_engine, statcache=self.gdata.statcache,radius_ipaddr=radius_ipaddr) rad_session.start(username,password).addCallbacks(sendresp,senderror) def stop_session(self,userdata): ipaddr = userdata.get('ipaddr','') session_id = userdata.get('session_id','') username = userdata.get('username','') RadiusSession.stop_session(ipaddr=ipaddr,session_id=session_id,username=username) self.radresp.push(msgpack.packb(['radstop_resp',dict(code=0,msg="session(%s,%s,%s) stop done"%(ipaddr,session_id,username))])) def process_poll(self): try: action, objdata = self.que.pop() except Exception as err: # logger.exception(err) reactor.callLater(1,self.process_poll) else: try: opfunc = self.ops.get(action) if opfunc: opfunc(objdata) else: logger.error('action %s not support'%action) except Exception as err: self.radresp.push(msgpack.packb(['%s_error'%action,dict(code=1,msg=repr(err))])) logger.exception(err) finally: reactor.callLater(0.001,self.process_poll)
def connect_subscriber(address): socket = ZmqSubConnection(ZmqFactory(), ZmqEndpoint("connect", address)) return socket
def sockjs_server(**options): configure = options.get('configure', False) port = options.get('port', 8888) sockjs_options = { 'websocket': True, 'cookie_needed': False, 'heartbeat': 25, 'timeout': 5, 'streaming_limit': 128 * 1024, 'encoding': 'cp1252', # Latin1 'sockjs_url': 'https://d1fxtkz8shb9d2.cloudfront.net/sockjs-0.3.js' } zf = ZmqFactory() endpoint = '%s://localhost:%d' % (settings.FORWARDER_PUB_TRANSPORT, settings.FORWARDER_PUB_PORT) e = ZmqEndpoint("connect", endpoint) subscription = ZmqSubConnection(zf, e) # Subscripción a todos los mensajes subscription.subscribe("") class SockJSProtocol(protocol.Protocol): DIRECT_FORWARD_MESSAGE_TYPES = ('echo', ) instances = [] def __init__(self, *largs, **kwargs): print "SockJS" #protocol.Protocol.__init__(*largs, **kwargs) SockJSProtocol.instances.append(self) def dataReceived(self, data_string): try: data = json.loads(data_string) msgtype = data.get('type', None) if msgtype in self.DIRECT_FORWARD_MESSAGE_TYPES: self.send_json(data, timestamp=repr(datetime.now())) except ValueError as e: print e self.send_json({'data': data_string, 'type': 'unknown'}) def send_json(self, data=None, **opts): '''Envia una respuesta en JSON por el websocket''' if data: if isinstance(data, dict): data_safe = copy(data) data_safe.update(opts) elif isinstance(data, basestring): try: data_safe = json.loads(data) except ValueError: raise ValueError("Can't convert %s to json" % data) else: data_safe = opts self.transport.write(json.dumps(data_safe)) def connectionLost(self, reason): print "Cerrando Socket" self.instances.remove(self) protocol.Protocol.connectionLost(self, reason) @classmethod def broadcast(cls, data, *largs, **kwargs): print "Received from forwarder %s" % data for conn in cls.instances: try: conn.send_json(data) except Exception as e: print e subscription.gotMessage = SockJSProtocol.broadcast factory = protocol.ServerFactory() factory.protocol = SockJSProtocol reactor.listenTCP(port, SockJSFactory(factory, sockjs_options)) print "SocketServer running on %d" % port if not configure: try: reactor.run() except error.ReactorNotRunning: print "Closing bridge"
pass class ProxyFactory(Factory): protocol = ProxyProtocol def main(): o = ServiceOptions() try: o.parseOptions() except usage.UsageError, msg: print "%s: %s" % (sys.argv[0], msg) print "%s: use --help for usage details" % (sys.argv[0],) raise SystemExit, 1 zf = ZmqFactory() sub = ZmqSubConnection(zf, ZmqEndpoint("connect", "tcp://%s" % o.opts['subsocket'])) sub.subscribe("") ws = listen("tcp:%s" % o.opts['websocket'], WebSocketFactory(ProxyFactory())) def forwardToWs(msg): for c in connections: c.transport.write(msg) sub.gotMessage = forwardToWs reactor.run() if __name__ == '__main__': main()
from rpi.config import ZMQ_PORT, local_configs ## publisher _context = zmq.Context() _pub_socket = _context.socket(zmq.PUB) _pub_socket.bind("tcp://*:{}".format(ZMQ_PORT)) def zmq_publish(msg): print('publishing "{}" to peers via 0mq'.format(msg)) _pub_socket.send(msg) ###### subscriber, for twisted ###### zf = ZmqFactory() subscriber = ZmqSubConnection(zf) def _create_endpoint(treename): return ZmqEndpoint( "connect", "tcp://{}:{}".format(local_configs['other_trees'][treename], ZMQ_PORT)) _endpoints = [ _create_endpoint(treename) for treename in local_configs['connect_to'] ] subscriber.addEndpoints(_endpoints) # in `main.py`, specific behavior is configured, such as:
dest="mode", help="Mode: publisher|subscriber") parser.set_defaults(method="connect", endpoint="epgm://eth1;239.0.5.3:10011") (options, args) = parser.parse_args() zf = ZmqFactory() e = ZmqEndpoint(options.method, options.endpoint) if options.mode == "publisher": s = ZmqPubConnection(zf, e) def publish(): data = str(time.time()) print "publishing %r" % data s.publish(data) reactor.callLater(1, publish) publish() else: s = ZmqSubConnection(zf, e) s.subscribe("") def doPrint(*args): print "message received: %r" % (args, ) s.gotMessage = doPrint reactor.run()
class ZMQfactory(): def __init__(self): self.pub_ = None self.sub_ = None self.req_ = None self.rep_ = None self.push_ = None self.pull_ = None self.timeout = 0.95 def set_timeout(self, timeout): self.timeout = timeout # pub sub 相关 def add_pub(self, endpoint): if endpoint: logger.debug("开始运行 PUB 服务器,服务地址为:{}...".format(endpoint)) self.pub_ = ZmqPubConnection(ZmqFactory(), ZmqEndpoint("bind", endpoint)) def add_sub(self, endpoint): if endpoint: logger.debug("开始运行 SUB 客户端 , 连接的服务器地址为:{}...".format(endpoint)) self.sub_ = ZmqSubConnection(ZmqFactory(), ZmqEndpoint("connect", endpoint)) self.set_callback() def set_filter(self, filter_=None): ''' 请输入需要接受的主题(必须调用该函数,否则无法收到任何数据) :param filter_: type str_list :return: ''' if self.sub_: if filter_: for item in filter_: self.sub_.subscribe(item.encode()) else: self.sub_.subscribe(b'') else: logger.error("请初始化SUB端口") def set_callback(self): if self.sub_: self.sub_.gotMessage = self.subscribeReceived else: logger.error("请初始化SUB端口") def subscribeReceived(self, *args): ''' 当接收到广播数据时,会触发该函数 :param data: :return: ''' def publishData(self, tag, data): ''' 从push服务器向外推送数据 :param tag: :param data: :return: ''' # req-rep 相关 def add_req(self, endpoint): ''' 设置 req 对象 :param endpoint: :return: ''' if endpoint: logger.debug("开始运行 REQ 服务器,连接地址为:{}...".format(endpoint)) self.req_ = ZmqREQConnection(ZmqFactory(), ZmqEndpoint('connect', endpoint)) def add_rep(self, endpoint, callBack=onPrint): ''' 设置 rep 对象 :param endpoint: :param callBack: :return: ''' if endpoint: logger.debug("开始运行 REP 服务器,监听地址为:{}...".format(endpoint)) self.rep_ = ZmqREPConnection(ZmqFactory(), ZmqEndpoint('bind', endpoint)) self.rep_.gotMessage = callBack def sendReq(self, data, callBack=onPrint, errBack=onTimeout): ''' 发送 req 信息 :param data: :param callBack: :param errBack: :return: ''' try: d = self.req_.sendMsg(data, timeout=self.timeout) d.addCallback(callBack).addErrback(errBack) except Exception as e: logger.error(e) # push pull 相关 def add_push(self, endpoint): ''' :param endpoint: :return: ''' if endpoint: logger.debug("开始运行 PUSH 服务器,监听地址为:{}...".format(endpoint)) self.push_ = ZmqPushConnection(ZmqFactory(), ZmqEndpoint('connect', endpoint)) def add_pull(self, endpoint, callBack=onPrint): ''' :param endpoint: :param callBack: :return: ''' if endpoint: logger.debug("开始运行 PULL 服务器,连接地址为:{}...".format(endpoint)) self.pull_ = ZmqPullConnection(ZmqFactory(), ZmqEndpoint('bind', endpoint)) self.pull_.onPull = callBack def pushData(self, data): ''' :param data: :return: ''' try: self.push_.push(data) except zmq.error.Again: logger.error("Skipping, no pull consumers...")
def add_sub(self, endpoint): if endpoint: logger.debug("开始运行 SUB 客户端 , 连接的服务器地址为:{}...".format(endpoint)) self.sub_ = ZmqSubConnection(ZmqFactory(), ZmqEndpoint("connect", endpoint)) self.set_callback()
def __init__(self, endpoint, wamp_session, prefix): self._endpoint = endpoint self._wamp = wamp_session self._prefix = prefix ZmqSubConnection.__init__(self, _zmq_factory, ZmqEndpoint('connect', endpoint.encode("utf-8"))) self.subscribe(b"")
def __init__(self, factory, subscribe_endpoint, miner): ZmqSubConnection.__init__(self, factory, subscribe_endpoint) self.miner = miner