Source code for mxcubecore.HardwareObjects.QtInstanceServer

import logging
import os
import pickle
import pwd
import socket
import time

import gevent
import gevent.server

from mxcubecore.BaseHardwareObjects import Procedure
from mxcubecore.utils import qt_import

"""
<procedure class="InstanceServer">
  <host>myhostname</host>
  <port>myport</port>
</procedure>
"""

TERMINATOR = "\0"
INSTANCE_HO = None
SERVER_CLIENTS = {}
CLIENTS = {}

###
# Creates an asynchronous TCP server to manage multiple application instances
###


[docs]class QtInstanceServer(Procedure): # Initializes the hardware object
[docs] def init(self): # Read the HO configuration self.serverPort = self.get_property("port") self.serverHost = self.get_property("host") if self.serverHost is None: self.serverHost = socket.getfqdn("") self.asyncServer = None self.instanceClient = None self.guiConfiguration = None self.idCount = {} # server only self.clients = {} # server only # self.serverId = None # to remove # self.controlId = None # to remove # self.myProposal = None # to remove self.clientId2 = [None, None] # client only self.serverId2 = [None, None] # client AND server self.controlId2 = [None, None] # client AND server self.bricksEventCache = {} global INSTANCE_HO INSTANCE_HO = self # Check the HO configuration if self.serverPort is None: self.log.error("InstanceServer: you must specify a port number") else: pass
def initialize_instance(self): for widget in qt_import.QApplication.allWidgets(): try: if hasattr(widget, "configuration"): self.guiConfiguration = widget.configuration break except NameError: logging.getLogger().warning( "Widget {} has no attribute {}".format(widget, "configuration") ) self.emit("instanceInitializing", ()) if self.isLocal(): self.startServer() else: self.connectToServer() def setProposal(self, proposal): if self.isServer(): my_id = self.serverId2[0] old_proposal = self.serverId2[1] msg = NewClientInstanceMessage() msg.setClientId(my_id) msg.setAvailable(True) msg.setProposal(old_proposal) msg.setNewProposal(proposal) data = msg.encode() broadcast_to_clients(data) self.serverId2[1] = proposal if self.controlId2[0] == my_id: self.controlId2[1] = proposal elif self.isClient(): my_id = self.clientId2[0] msg = NewClientInstanceMessage() msg.setNewProposal(proposal) data = msg.encode() send_data_to_server(self.instanceClient, data) self.clientId2[1] = proposal if self.controlId2[0] == my_id: self.controlId2[1] = proposal def idPrettyPrint(self, user_id, use_proposal=True): my_nick = "" pretty_print = "" if self.isServer(): my_nick = self.serverId2[0] elif self.isClient(): my_nick = self.clientId2[0] else: self.log.warning( "InstanceServer: printing an id while not server nor client" ) if user_id is None: pretty_print = my_nick else: nick = user_id[0] prop = user_id[1] if my_nick != nick: if use_proposal: if prop is not None: pretty_print = "[%s%s]%s" % (prop["code"], prop["number"], nick) else: pretty_print = "[?]%s" % nick else: pretty_print = nick else: pretty_print = my_nick return pretty_print # Starts the server def startServer(self): if self.asyncServer is not None: self.log.error("InstanceServer: server already started") elif self.serverPort is not None: try: async_server = gevent.server.StreamServer( (self.serverHost, self.serverPort), handleRemoteClient ) # AsyncServer(self,self.serverHost,self.serverPort) async_server.start() except Exception: self.log.warning( "InstanceServer: cannot create server, so trying to connect to it" ) self.connectToServer() else: self.asyncServer = async_server server_hostname = self.serverHost.split(".")[0] self.log.debug( "InstanceServer: listening to connections on %s:%d" % (server_hostname, self.serverPort) ) self.serverId2[0] = server_hostname self.controlId2 = list(self.serverId2) self.idCount[server_hostname] = 1 self.emit("serverInitialized", (True, self.serverId2)) else: self.log.error( "InstanceServer: not property configured to start the server" ) self.emit("serverInitialized", (False,)) # Closes the server def closeServer(self): self.asyncServer.close() self.asyncServer = None def connectToServer(self, quiet=False): self.emit("clientInitialized", (None,)) self.reconnect(quiet) # Connects to the server def reconnect(self, quiet=False): try: self.instanceClient = InstanceClient(self.serverHost, self.serverPort) except Exception: self.instanceClient = None if not quiet: self.log.error("InstanceServer: cannot connect to server") self.emit("clientInitialized", (False, (None, None), None, quiet)) else: my_login = pwd.getpwuid(os.getuid())[0] msg = AskPermissionInstanceMessage() msg.setClientId(my_login) msg.setProposal(self.clientId2[1]) data = msg.encode() send_data_to_server(self.instanceClient, data) def isLocal(self): try: display = os.environ["DISPLAY"].split(":")[0] except Exception: return False if not display: return True return socket.getfqdn(display) == self.serverHost def isServer(self): return self.asyncServer is not None def isClient(self): return self.instanceClient is not None def inControl(self): return self.controlId2 def serverClosed(self): self.log.error("InstanceServer: server has closed the connection!") self.emit("serverClosed", (self.serverId2,)) def clientConnected(self, addr, req_handler): return def clientClosed(self, addr): # print "CLIENT CLOSED",addr,self.clients found_id = None found_prop = None for cli_id in self.clients: cli_addr = self.clients[cli_id][0] cli_prop = self.clients[cli_id][1] if cli_addr == addr: self.clients.pop(cli_id) found_id = cli_id found_prop = cli_prop self.emit("clientClosed", ((cli_id, cli_prop),)) break if found_id is not None: msg = NewClientInstanceMessage() msg.setClientId(found_id) msg.setProposal(found_prop) msg.setAvailable(False) data = msg.encode() broadcast_to_clients(data) if self.controlId2[0] == found_id: self.controlId2 = list(self.serverId2) msg = PassControlInstanceMessage() msg.setClientId(self.controlId2[0]) msg.setProposal(self.controlId2[1]) data = msg.encode() broadcast_to_clients(data) self.emit("haveControl", (True,)) def requestIdChange(self, new_id): if self.isServer(): msg = NewClientInstanceMessage() try: count = self.idCount[new_id] except KeyError: self.idCount[new_id] = 1 else: count += 1 self.idCount[new_id] = count new_id = "%s-%d" % (new_id, count) self.idCount[new_id] = 1 msg.setClientNewId(new_id) msg.setClientId(self.serverId2[0]) msg.setAvailable(True) msg.setProposal(self.serverId2[1]) data = msg.encode() broadcast_to_clients(data) old_id = self.serverId2[0] old_prop = self.serverId2[1] self.serverId2[0] = new_id if self.controlId2[0] == old_id: self.controlId2[0] = new_id new_prop = old_prop self.emit("clientChanged", ((old_id, old_prop), (new_id, new_prop))) elif self.isClient(): msg = NewClientInstanceMessage() msg.setClientNewId(new_id) data = msg.encode() send_data_to_server(self.instanceClient, data) else: self.log.warning( "InstanceServer: requestIdChange while not server nor client!" ) def sendChatMessage(self, priority, message): msg = ChatInstanceMessage() msg.setChatMessage(priority, message) if self.isServer(): msg.setChatNick(self.serverId2[0]) msg.setProposal(self.serverId2[1]) my_id = self.serverId2 data = msg.encode() if self.isServer(): broadcast_to_clients(data) elif self.isClient(): send_data_to_server(self.instanceClient, data) my_id = self.clientId2 else: self.log.warning( "InstanceServer: sendChatMessage while not server nor client!" ) self.emit("chatMessageReceived", (priority, my_id, message)) def addEventToCache(self, brick_name, widget_name, message_data): self.bricksEventCache[(brick_name, widget_name)] = message_data def synchronizeClientWithEvents(self, client_addr): for event_data in list(self.bricksEventCache.values()): send_data_to_client(client_addr, event_data) def sendBrickUpdateMessage( self, brick_name, widget_name, widget_method, widget_method_args, masterSync ): msg = BrickUpdateInstanceMessage() msg.setBrickUpdate( brick_name, widget_name, widget_method, widget_method_args, masterSync ) data = msg.encode() if self.isServer(): self.addEventToCache(brick_name, widget_name, data) broadcast_to_clients(data) elif self.isClient(): send_data_to_server(self.instanceClient, data) else: self.log.warning( "InstanceServer: sendBrickUpdateMessage while not server nor client!" ) def sendTabUpdateMessage(self, tab_name, tab_index): msg = TabUpdateInstanceMessage() msg.setTabUpdate(tab_name, tab_index) data = msg.encode() self.addEventToCache(None, tab_name, data) if self.isServer(): broadcast_to_clients(data) elif self.isClient(): send_data_to_server(self.instanceClient, data) else: self.log.warning( "InstanceServer: sendTabUpdateMessage while not server nor client!" ) def giveControl(self, client_id): if self.isServer(): try: client_addr = self.clients[client_id[0]][0] except KeyError: pass else: client_prop = self.clients[client_id[0]][1] self.controlId2 = [client_id[0], client_prop] msg = ControlInstanceMessage() msg.setHasControl(True) data = msg.encode() send_data_to_client(client_addr, data) msg = PassControlInstanceMessage() msg.setClientId(client_id[0]) msg.setProposal(client_prop) data = msg.encode() broadcast_to_clients(data, avoid=(client_addr,)) self.emit("passControl", ((client_id[0], client_prop),)) self.emit("haveControl", (False,)) elif self.isClient(): msg = PassControlInstanceMessage() msg.setClientId(client_id[0]) msg.setProposal(client_id[1]) data = msg.encode() send_data_to_server(self.instanceClient, data) else: self.log.warning("InstanceServer: giveControl while not server nor client!") def askForControl(self): msg = AskControlInstanceMessage() if self.isClient(): data = msg.encode() send_data_to_server(self.instanceClient, data) else: msg.setClientId(self.serverId2[0]) msg.setProposal(self.serverId2[1]) data = msg.encode() broadcast_to_clients(data) def takeControl(self): if self.isServer(): if self.controlId2[0] != self.serverId2[0]: client_addr = self.clients[self.controlId2[0]][0] msg = ControlInstanceMessage() msg.setHasControl(False) data = msg.encode() send_data_to_client(client_addr, data) self.controlId2 = list(self.serverId2) msg = PassControlInstanceMessage() msg.setClientId(self.controlId2[0]) msg.setProposal(self.controlId2[1]) data = msg.encode() broadcast_to_clients(data) self.emit("haveControl", (True,)) else: self.log.warning( "InstanceServer: takeControl while already in control!" ) elif self.isClient(): if self.controlId2[0] != self.clientId2[0]: msg = TakeControlInstanceMessage() data = msg.encode() send_data_to_server(self.instanceClient, data) else: self.log.warning( "InstanceServer: takeControl while already in control!" ) def callInControl(self, brick, method, method_args): msg = BrickCallInstanceMessage() brick_name = brick.name() widget_name = "" msg.setBrickUpdate(brick_name, widget_name, method, method_args) data = msg.encode() if self.isServer(): if self.controlId2[0] != self.serverId2[0]: client_addr = self.clients[self.controlId2[0]][0] send_data_to_client(client_addr, data) else: self.log.warning( "InstanceServer: calling a brick while having control!" ) else: self.log.warning("InstanceServer: only the server can call a brick!") def answerToServer(self, brick, method, method_args): msg = BrickCallInstanceMessage() brick_name = brick.name() widget_name = "" msg.setBrickUpdate(brick_name, widget_name, method, method_args) data = msg.encode() if self.isServer(): self.log.warning("InstanceServer: only a client can answer to the server!") else: data = msg.encode() send_data_to_server(self.instanceClient, data) def parseReceivedMessage(self, data): # logging.getLogger().debug("******** RECEIVED MESSAGE = %r", data) msg_obj = None try: message = InstanceMessage(data=data) except Exception: self.log.exception("InstanceServer: problem parsing received message") else: try: t = message.getType() except Exception: self.log.exception("InstanceServer: problem parsing received message") else: if t == InstanceMessage.TYPE_CHAT: msg_obj = ChatInstanceMessage(message) elif t == InstanceMessage.TYPE_CONTROL: msg_obj = ControlInstanceMessage(message) elif t == InstanceMessage.TYPE_ASKPERMISSION: msg_obj = AskPermissionInstanceMessage(message) elif t == InstanceMessage.TYPE_GIVEPERMISSION: msg_obj = GivePermissionInstanceMessage(message) elif t == InstanceMessage.TYPE_NEWCLIENT: msg_obj = NewClientInstanceMessage(message) elif t == InstanceMessage.TYPE_ASKCONTROL: msg_obj = AskControlInstanceMessage(message) elif t == InstanceMessage.TYPE_PASSCONTROL: msg_obj = PassControlInstanceMessage(message) elif t == InstanceMessage.TYPE_BRICKUPDATE: msg_obj = BrickUpdateInstanceMessage(message) elif t == InstanceMessage.TYPE_TABUPDATE: msg_obj = TabUpdateInstanceMessage(message) elif t == InstanceMessage.TYPE_TAKECONTROL: msg_obj = TakeControlInstanceMessage(message) elif t == InstanceMessage.TYPE_BRICKCALL: msg_obj = BrickCallInstanceMessage(message) else: self.log.warning( "InstanceServer: unknown message type %s " % str(t) ) return msg_obj def clientMessageReceived(self, data): m = self.parseReceivedMessage(data) if m is None: return if isinstance(m, ChatInstanceMessage): self.emit( "chatMessageReceived", ( m.getChatPriority(), (m.getChatNick(), m.getProposal()), m.getChatMessage(), ), ) elif isinstance(m, ControlInstanceMessage): has_control = m.getHasControl() self.emit("haveControl", (has_control,)) elif isinstance(m, NewClientInstanceMessage): client_id = m.getClientId() client_proposal = m.getProposal() try: new_client_id = m.getClientNewId() except KeyError: try: new_proposal = m.getNewProposal() except KeyError: a = m.getAvailable() if a: self.emit("newClient", ((client_id, client_proposal),)) else: self.emit("clientClosed", ((client_id, client_proposal),)) else: if client_id == self.serverId2[0]: self.serverId2[1] = new_proposal self.emit( "clientChanged", ((client_id, client_proposal), (client_id, new_proposal)), ) else: if client_id == self.serverId2[0]: self.serverId2[0] = new_client_id self.emit( "clientChanged", ((client_id, client_proposal), (new_client_id, client_proposal)), ) elif isinstance(m, GivePermissionInstanceMessage): self.serverId2 = [m.getServerId(), m.getProposal()] self.clientId2[0] = m.getClientId() self.emit( "clientInitialized", (True, (m.getServerId(), m.getProposal()), m.getClientId()), ) elif isinstance(m, AskControlInstanceMessage): client_id = m.getClientId() try: client_prop = m.getProposal() except Exception: client_prop = None self.emit("wantsControl", ((client_id, client_prop),)) elif isinstance(m, PassControlInstanceMessage): client_id = m.getClientId() client_proposal = m.getProposal() self.controlId2 = [client_id, client_proposal] self.emit("passControl", ((client_id, client_proposal),)) elif isinstance(m, BrickCallInstanceMessage): try: timestamp = m.getTimestamp() brick_name = m.getBrickName() widget_name = m.getWidgetName() widget_method = m.getWidgetMethod() widget_method_args = m.getWidgetMethodArgs() brick = self.guiConfiguration.findItem(brick_name).brick if widget_name == "": exec("method=brick.%s" % widget_method) else: exec("method=brick.%s.%s" % (widget_name, widget_method)) self.emit("widgetCall", (timestamp, method, widget_method_args)) except Exception: self.log.exception("InstanceServer: problem while calling a brick!") elif isinstance(m, BrickUpdateInstanceMessage): try: timestamp = m.getTimestamp() brick_name = m.getBrickName() widget_name = m.getWidgetName() widget_method = m.getWidgetMethod() widget_method_args = m.getWidgetMethodArgs() masterSync = m.getMasterSync() # if necessary check this with Qt3 version brick = self.guiConfiguration.findItem(brick_name).get("brick") if widget_name == "": exec("method=brick.%s" % widget_method) else: exec("method=brick.%s.%s" % (widget_name, widget_method)) self.emit( "widgetUpdate", (timestamp, method, widget_method_args, masterSync) ) except Exception: self.log.exception("InstanceServer: problem while updating a brick!") elif isinstance(m, TabUpdateInstanceMessage): try: timestamp = m.getTimestamp() tab_name = m.getTabName() tab_index = m.getTabIndex() tab = self.guiConfiguration.findItem(tab_name).widget method = tab.setCurrentPage method_args = (tab_index,) self.emit("widgetUpdate", (timestamp, method, method_args)) except Exception: self.log.exception("InstanceServer: problem while updating a tab!") def serverMessageReceived(self, client_addr, data): m = self.parseReceivedMessage(data) if m is None: return if isinstance(m, NewClientInstanceMessage): try: client_new_id = m.getClientNewId() except KeyError: new_proposal = m.getNewProposal() # print "SERVER NEWCLIENT PROPOSAL",new_proposal,self.clients found_id = None for cli_id in self.clients: cli_addr = self.clients[cli_id][0] if cli_addr == client_addr: found_id = cli_id cli_prop = self.clients[cli_id][1] msg = NewClientInstanceMessage() msg.setClientId(cli_id) msg.setProposal(cli_prop) msg.setNewProposal(new_proposal) msg.setAvailable(True) data = msg.encode() broadcast_to_clients(data) self.emit( "clientChanged", ((cli_id, cli_prop), (cli_id, new_proposal)), ) break if found_id is not None: if self.controlId2[0] == found_id: self.controlId2[1] = new_proposal self.clients[cli_id][1] = new_proposal else: try: count = self.idCount[client_new_id] except KeyError: self.idCount[client_new_id] = 1 else: count += 1 self.idCount[client_new_id] = count client_new_id = "%s-%d" % (client_new_id, count) self.idCount[client_new_id] = 1 found_id = None for cli_id in self.clients: cli_addr = self.clients[cli_id][0] if cli_addr == client_addr: found_id = cli_id cli_prop = self.clients[cli_id][1] msg = NewClientInstanceMessage() msg.setClientId(cli_id) msg.setClientNewId(client_new_id) msg.setProposal(cli_prop) msg.setAvailable(True) data = msg.encode() broadcast_to_clients(data) self.emit( "clientChanged", ((cli_id, cli_prop), (client_new_id, cli_prop)), ) break if found_id is not None: if self.controlId2[0] == found_id: self.controlId2[0] = client_new_id self.clients[client_new_id] = self.clients[found_id] self.clients.pop(found_id) elif isinstance(m, AskPermissionInstanceMessage): client_id = m.getClientId() client_proposal = m.getProposal() try: count = self.idCount[client_id] except KeyError: self.idCount[client_id] = 1 else: count += 1 self.idCount[client_id] = count client_id = "%s-%d" % (client_id, count) self.idCount[client_id] = 1 self.clients[client_id] = [client_addr, client_proposal] msg = NewClientInstanceMessage() msg.setClientId(client_id) msg.setProposal(client_proposal) msg.setAvailable(True) data = msg.encode() broadcast_to_clients(data, avoid=(client_addr,)) for cli_id in self.clients: if cli_id != client_id: msg = NewClientInstanceMessage() cli_addr = self.clients[cli_id][0] cli_prop = self.clients[cli_id][1] msg.setClientId(cli_id) msg.setProposal(cli_prop) msg.setAvailable(True) data = msg.encode() send_data_to_client(client_addr, data) self.synchronizeClientWithEvents(client_addr) msg = GivePermissionInstanceMessage() msg.setClientId(client_id) msg.setServerId(self.serverId2[0]) msg.setProposal(self.serverId2[1]) data = msg.encode() send_data_to_client(client_addr, data) msg = PassControlInstanceMessage() msg.setClientId(self.controlId2[0]) msg.setProposal(self.controlId2[1]) data = msg.encode() send_data_to_client(client_addr, data) self.emit("newClient", ((client_id, client_proposal),)) elif isinstance(m, ChatInstanceMessage): found_id = None for cli_id in self.clients: cli_addr = self.clients[cli_id][0] if cli_addr == client_addr: found_id = cli_id found_prop = self.clients[cli_id][1] if found_id is not None: m.setChatNick(found_id) m.setProposal(found_prop) data = m.encode() broadcast_to_clients(data, avoid=(client_addr,)) self.emit( "chatMessageReceived", (m.getChatPriority(), (found_id, found_prop), m.getChatMessage()), ) elif isinstance(m, AskControlInstanceMessage): found_id = None found_prop = None for cli_id in self.clients: cli_addr = self.clients[cli_id][0] if cli_addr == client_addr: found_id = cli_id found_prop = self.clients[cli_id][1] if found_id is not None: m.setClientId(found_id) if found_prop is not None: m.setProposal(found_prop) data = m.encode() broadcast_to_clients(data) self.emit("wantsControl", ((found_id, found_prop),)) elif isinstance(m, PassControlInstanceMessage): client_id = m.getClientId() if self.serverId2[0] == client_id: self.takeControl() else: try: cli_addr = self.clients[client_id][0] except KeyError: pass else: client_prop = self.clients[client_id][1] msg = ControlInstanceMessage() msg.setHasControl(False) data = msg.encode() send_data_to_client(client_addr, data) msg = PassControlInstanceMessage() msg.setClientId(client_id) msg.setProposal(client_prop) data = msg.encode() broadcast_to_clients(data, avoid=(cli_addr,)) self.controlId2 = [client_id, client_prop] self.emit("passControl", ((client_id, client_prop),)) msg = ControlInstanceMessage() msg.setHasControl(True) data = msg.encode() send_data_to_client(cli_addr, data) elif isinstance(m, BrickCallInstanceMessage): try: timestamp = m.getTimestamp() brick_name = m.getBrickName() widget_name = m.getWidgetName() widget_method = m.getWidgetMethod() widget_method_args = m.getWidgetMethodArgs() brick = self.guiConfiguration.findItem(brick_name).brick if widget_name == "": exec("method=brick.%s" % widget_method) else: exec("method=brick.%s.%s" % (widget_name, widget_method)) self.emit("widgetCall", (timestamp, method, widget_method_args)) except Exception: self.log.exception("InstanceServer: problem while calling a brick!") elif isinstance(m, BrickUpdateInstanceMessage): broadcast_to_clients(data, avoid=(client_addr,)) try: timestamp = m.getTimestamp() brick_name = m.getBrickName() widget_name = m.getWidgetName() widget_method = m.getWidgetMethod() widget_method_args = m.getWidgetMethodArgs() brick = self.guiConfiguration.findItem(brick_name).brick masterSync = m.getMasterSync() if widget_name == "": exec("method=brick.%s" % widget_method) else: exec("method=brick.%s.%s" % (widget_name, widget_method)) self.emit( "widgetUpdate", (timestamp, method, widget_method_args, masterSync) ) except Exception: self.log.exception("InstanceServer: problem while updating a brick!") elif isinstance(m, TabUpdateInstanceMessage): broadcast_to_clients(data, avoid=(client_addr,)) try: timestamp = m.getTimestamp() tab_name = m.getTabName() tab_index = m.getTabIndex() tab = self.guiConfiguration.findItem(tab_name).widget method = tab.setCurrentPage method_args = (tab_index,) self.emit("widgetUpdate", (timestamp, method, method_args)) except Exception: self.log.exception("InstanceServer: problem while updating a tab!") elif isinstance(m, TakeControlInstanceMessage): found_id = None found_prop = None for cli_id in self.clients: cli_addr = self.clients[cli_id][0] if cli_addr == client_addr: found_id = cli_id found_prop = self.clients[cli_id][1] if found_id is not None: if self.controlId2[0] == self.serverId2[0]: self.emit("haveControl", (False,)) else: control_addr = self.clients[self.controlId2[0]][0] msg = ControlInstanceMessage() msg.setHasControl(False) data = msg.encode() send_data_to_client(control_addr, data) msg = PassControlInstanceMessage() msg.setClientId(found_id) msg.setProposal(found_prop) data = msg.encode() broadcast_to_clients(data) self.controlId2 = [found_id, found_prop] self.emit("passControl", ((found_id, found_prop),)) msg = ControlInstanceMessage() msg.setHasControl(True) data = msg.encode() send_data_to_client(cli_addr, data)
def handleRemoteClient(client_socket, addr): SERVER_CLIENTS[addr] = client_socket INSTANCE_HO.clientConnected(addr, client_socket) buffer = "" while True: data = client_socket.recv(1024) if data == "": try: SERVER_CLIENTS.pop(addr) except Exception: # Huh? socket closed but client is not in SERVER_CLIENTS dict! # just ignore silently pass else: INSTANCE_HO.clientClosed(addr) break buffer += data msgs = buffer.split(TERMINATOR) buffer = msgs.pop() for msg in msgs: INSTANCE_HO.serverMessageReceived(addr, msg) def broadcast_to_clients(data, avoid=None): for client_addr in list(SERVER_CLIENTS.keys()): if avoid and client_addr in avoid: continue send_data_to_client(client_addr, data) def send_data_to_client(client_addr, data): client_socket = SERVER_CLIENTS.get(client_addr) if client_socket: try: client_socket.sendall("%s%s" % (data, TERMINATOR)) except Exception: # broken pipe? client disconnected SERVER_CLIENTS.pop(client_addr) def InstanceClient(host, port): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.connect((host, port)) except Exception: raise else: socketName = s.getsockname() def handle_incoming_data(client_socket): buffer = "" while True: data = client_socket.recv(1024) if data == "": INSTANCE_HO.serverClosed() break buffer += data msgs = buffer.split(TERMINATOR) buffer = msgs.pop() for msg in msgs: INSTANCE_HO.clientMessageReceived(msg) CLIENTS[socketName] = s gevent.spawn(handle_incoming_data, s) return socketName def send_data_to_server(socket_name, data): client_socket = CLIENTS[socket_name] client_socket.sendall("%s%s" % (data, TERMINATOR)) class InstanceMessage: ( TYPE_CHAT, TYPE_CONTROL, TYPE_NEWCLIENT, TYPE_ASKPERMISSION, TYPE_GIVEPERMISSION, TYPE_ASKCONTROL, TYPE_PASSCONTROL, TYPE_BRICKUPDATE, TYPE_TABUPDATE, TYPE_TAKECONTROL, TYPE_BRICKCALL, ) = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) def __init__(self, data=None): self.messageDict = {} if data is not None: self.messageDict = pickle.loads(data) def encode(self): try: self.messageDict["type"] except KeyError: raise ValueError return pickle.dumps(self.messageDict) def getType(self): try: t = self.messageDict["type"] except KeyError: raise ValueError return t class ChatInstanceMessage(InstanceMessage): (PRIORITY_LOW, PRIORITY_NORMAL, PRIORITY_HIGH) = (0, 1, 2) def __init__(self, instance_message=None): InstanceMessage.__init__(self) if instance_message is not None: self.messageDict = instance_message.messageDict self.messageDict["type"] = InstanceMessage.TYPE_CHAT def setChatMessage(self, priority, message): self.messageDict["priority"] = priority self.messageDict["message"] = message def setChatNick(self, nick): self.messageDict["nick"] = nick def getChatMessage(self): return self.messageDict["message"] def getChatPriority(self): return self.messageDict["priority"] def getChatNick(self): return self.messageDict["nick"] def setProposal(self, proposal): self.messageDict["proposal"] = proposal def getProposal(self): return self.messageDict["proposal"] class ControlInstanceMessage(InstanceMessage): def __init__(self, instance_message=None): InstanceMessage.__init__(self) if instance_message is not None: self.messageDict = instance_message.messageDict self.messageDict["type"] = InstanceMessage.TYPE_CONTROL def setHasControl(self, has_control): self.messageDict["control"] = has_control def getHasControl(self): return self.messageDict["control"] class PassControlInstanceMessage(InstanceMessage): def __init__(self, instance_message=None): InstanceMessage.__init__(self) if instance_message is not None: self.messageDict = instance_message.messageDict self.messageDict["type"] = InstanceMessage.TYPE_PASSCONTROL def setClientId(self, client_id): self.messageDict["client_id"] = client_id def getClientId(self): return self.messageDict["client_id"] def setProposal(self, proposal): self.messageDict["proposal"] = proposal def getProposal(self): return self.messageDict["proposal"] class AskControlInstanceMessage(InstanceMessage): def __init__(self, instance_message=None): InstanceMessage.__init__(self) if instance_message is not None: self.messageDict = instance_message.messageDict self.messageDict["type"] = InstanceMessage.TYPE_ASKCONTROL def setClientId(self, client_id): self.messageDict["client_id"] = client_id def getClientId(self): return self.messageDict["client_id"] def setProposal(self, proposal): self.messageDict["proposal"] = proposal def getProposal(self): return self.messageDict["proposal"] class AskPermissionInstanceMessage(InstanceMessage): def __init__(self, instance_message=None): InstanceMessage.__init__(self) if instance_message is not None: self.messageDict = instance_message.messageDict self.messageDict["type"] = InstanceMessage.TYPE_ASKPERMISSION def setClientId(self, client_id): self.messageDict["client_id"] = client_id def getClientId(self): return self.messageDict["client_id"] def setProposal(self, proposal): self.messageDict["proposal"] = proposal def getProposal(self): return self.messageDict["proposal"] class GivePermissionInstanceMessage(InstanceMessage): def __init__(self, instance_message=None): InstanceMessage.__init__(self) if instance_message is not None: self.messageDict = instance_message.messageDict self.messageDict["type"] = InstanceMessage.TYPE_GIVEPERMISSION def setClientId(self, client_id): self.messageDict["client_id"] = client_id def getClientId(self): return self.messageDict["client_id"] def setServerId(self, server_id): self.messageDict["server_id"] = server_id def getServerId(self): return self.messageDict["server_id"] def setProposal(self, proposal): self.messageDict["proposal"] = proposal def getProposal(self): return self.messageDict["proposal"] class NewClientInstanceMessage(InstanceMessage): def __init__(self, instance_message=None): InstanceMessage.__init__(self) if instance_message is not None: self.messageDict = instance_message.messageDict self.messageDict["type"] = InstanceMessage.TYPE_NEWCLIENT def setClientId(self, client_id): self.messageDict["client_id"] = client_id def getClientId(self): return self.messageDict["client_id"] def setClientNewId(self, client_new_id): self.messageDict["client_new_id"] = client_new_id def getClientNewId(self): return self.messageDict["client_new_id"] def setAvailable(self, available): self.messageDict["available"] = available def getAvailable(self): return self.messageDict["available"] def setProposal(self, proposal): self.messageDict["proposal"] = proposal def getProposal(self): return self.messageDict["proposal"] def setNewProposal(self, proposal): self.messageDict["new_proposal"] = proposal def getNewProposal(self): return self.messageDict["new_proposal"] class BrickUpdateInstanceMessage(InstanceMessage): def __init__(self, instance_message=None): InstanceMessage.__init__(self) if instance_message is not None: self.messageDict = instance_message.messageDict self.messageDict["type"] = InstanceMessage.TYPE_BRICKUPDATE def setBrickUpdate( self, brick_name, widget_name, widget_method, widget_method_args, masterSync=True, ): self.messageDict["timestamp"] = time.time() self.messageDict["brick_name"] = brick_name self.messageDict["widget_name"] = widget_name self.messageDict["widget_method"] = widget_method self.messageDict["widget_method_args"] = widget_method_args self.messageDict["masterSync"] = masterSync def getTimestamp(self): return self.messageDict["timestamp"] def getBrickName(self): return self.messageDict["brick_name"] def getWidgetName(self): return self.messageDict["widget_name"] def getWidgetMethod(self): return self.messageDict["widget_method"] def getWidgetMethodArgs(self): return self.messageDict["widget_method_args"] def getMasterSync(self): return self.messageDict["masterSync"] class TabUpdateInstanceMessage(InstanceMessage): def __init__(self, instance_message=None): InstanceMessage.__init__(self) if instance_message is not None: self.messageDict = instance_message.messageDict self.messageDict["type"] = InstanceMessage.TYPE_TABUPDATE def setTabUpdate(self, tab_name, tab_index): self.messageDict["timestamp"] = time.time() self.messageDict["tab_name"] = tab_name self.messageDict["tab_index"] = tab_index def getTimestamp(self): return self.messageDict["timestamp"] def getTabName(self): return self.messageDict["tab_name"] def getTabIndex(self): return self.messageDict["tab_index"] class TakeControlInstanceMessage(InstanceMessage): def __init__(self, instance_message=None): InstanceMessage.__init__(self) if instance_message is not None: self.messageDict = instance_message.messageDict self.messageDict["type"] = InstanceMessage.TYPE_TAKECONTROL class BrickCallInstanceMessage(BrickUpdateInstanceMessage): def __init__(self, instance_message=None): InstanceMessage.__init__(self) if instance_message is not None: self.messageDict = instance_message.messageDict self.messageDict["type"] = InstanceMessage.TYPE_BRICKCALL