runtime/WampClient.py
changeset 3343 c6de1a6cb655
parent 3342 d8e99ecde9a2
child 3440 3770ded5db5c
equal deleted inserted replaced
3341:dce1d5413310 3343:c6de1a6cb655
    73 # de-activated dumb wamp config
    73 # de-activated dumb wamp config
    74 defaultWampConfig = {
    74 defaultWampConfig = {
    75     "ID": "wamptest",
    75     "ID": "wamptest",
    76     "active": False,
    76     "active": False,
    77     "realm": "Automation",
    77     "realm": "Automation",
    78     "url": "ws://127.0.0.1:8888"
    78     "url": "ws://127.0.0.1:8888",
       
    79     "clientFactoryOptions": {
       
    80         "maxDelay": 300
       
    81     },
       
    82     "protocolOptions": {
       
    83         "autoPingInterval": 10,
       
    84         "autoPingTimeout": 5
       
    85     }
    79 }
    86 }
    80 
    87 
    81 # Those two lists are meant to be filled by customized runtime
    88 # Those two lists are meant to be filled by customized runtime
    82 # or User python code.
    89 # or User python code.
    83 
    90 
   160     def __init__(self, config, *args, **kwargs):
   167     def __init__(self, config, *args, **kwargs):
   161         global _transportFactory
   168         global _transportFactory
   162         WampWebSocketClientFactory.__init__(self, *args, **kwargs)
   169         WampWebSocketClientFactory.__init__(self, *args, **kwargs)
   163 
   170 
   164         try:
   171         try:
       
   172             clientFactoryOptions = config.extra.get("clientFactoryOptions")
       
   173             if clientFactoryOptions:
       
   174                 self.setClientFactoryOptions(clientFactoryOptions)
       
   175         except Exception as e:
       
   176             print(_("Custom client factory options failed : "), e)
       
   177             _transportFactory = None
       
   178 
       
   179         try:
   165             protocolOptions = config.extra.get('protocolOptions', None)
   180             protocolOptions = config.extra.get('protocolOptions', None)
   166             if protocolOptions:
   181             if protocolOptions:
   167                 self.setProtocolOptions(**protocolOptions)
   182                 self.setProtocolOptions(**protocolOptions)
   168             _transportFactory = self
   183             _transportFactory = self
   169         except Exception as e:
   184         except Exception as e:
   170             print(_("Custom protocol options failed :"), e)
   185             print(_("Custom protocol options failed :"), e)
   171             _transportFactory = None
   186             _transportFactory = None
   172 
   187 
       
   188     def setClientFactoryOptions(self, options):
       
   189         for key, value in options.items():
       
   190             if key in ["maxDelay", "initialDelay", "maxRetries", "factor", "jitter"]:
       
   191                 setattr(self, key, value)
       
   192 
   173     def buildProtocol(self, addr):
   193     def buildProtocol(self, addr):
   174         self.resetDelay()
   194         self.resetDelay()
   175         return ReconnectingClientFactory.buildProtocol(self, addr)
   195         return ReconnectingClientFactory.buildProtocol(self, addr)
   176 
   196 
   177     def clientConnectionFailed(self, connector, reason):
   197     def clientConnectionFailed(self, connector, reason):
   192     if not IsCorrectUri(url):
   212     if not IsCorrectUri(url):
   193         raise annotate.ValidateError(
   213         raise annotate.ValidateError(
   194             {"url": "Invalid URL: {}".format(url)},
   214             {"url": "Invalid URL: {}".format(url)},
   195             _("WAMP configuration error:"))
   215             _("WAMP configuration error:"))
   196 
   216 
       
   217 def UpdateWithDefault(d1, d2):
       
   218     for k, v in d2.items():
       
   219         d1.setdefault(k, v)
   197 
   220 
   198 def GetConfiguration():
   221 def GetConfiguration():
   199     global lastKnownConfig
   222     global lastKnownConfig
   200 
   223 
   201     WampClientConf = None
   224     WampClientConf = None
   202 
   225 
   203     if os.path.exists(_WampConf):
   226     if os.path.exists(_WampConf):
   204         try: 
   227         try: 
   205             WampClientConf = json.load(open(_WampConf))
   228             WampClientConf = json.load(open(_WampConf))
       
   229             UpdateWithDefault(WampClientConf, defaultWampConfig)
   206         except ValueError:
   230         except ValueError:
   207             pass
   231             pass
   208 
   232 
   209     if WampClientConf is None:
   233     if WampClientConf is None:
   210         WampClientConf = defaultWampConfig.copy()
   234         WampClientConf = defaultWampConfig.copy()
   318         _WampSession.leave()
   342         _WampSession.leave()
   319 
   343 
   320 
   344 
   321 def StartReconnectWampClient():
   345 def StartReconnectWampClient():
   322     if _WampSession:
   346     if _WampSession:
   323         # do reconnect
   347         # do reconnect and reset continueTrying and initialDelay parameter
       
   348         if _transportFactory is not None:
       
   349             _transportFactory.resetDelay()
   324         _WampSession.disconnect()
   350         _WampSession.disconnect()
   325         return True
   351         return True
   326     else:
   352     else:
   327         # do connect
   353         # do connect
   328         RegisterWampClient()
   354         RegisterWampClient()
   358         _WampSession.publishWithOwnID(text(eventID), value)
   384         _WampSession.publishWithOwnID(text(eventID), value)
   359 
   385 
   360 
   386 
   361 # WEB CONFIGURATION INTERFACE
   387 # WEB CONFIGURATION INTERFACE
   362 WAMP_SECRET_URL = "secret"
   388 WAMP_SECRET_URL = "secret"
   363 webExposedConfigItems = ['active', 'url', 'ID']
   389 webExposedConfigItems = [
       
   390     'active', 'url', 'ID',
       
   391     "clientFactoryOptions.maxDelay",
       
   392     "protocolOptions.autoPingInterval",
       
   393     "protocolOptions.autoPingTimeout"
       
   394 ]
   364 
   395 
   365 
   396 
   366 def wampConfigDefault(ctx, argument):
   397 def wampConfigDefault(ctx, argument):
   367     if lastKnownConfig is not None:
   398     if lastKnownConfig is not None:
   368         return lastKnownConfig.get(argument.name, None)
   399         # Check if name is composed with an intermediate dot symbol and go deep in lastKnownConfig if it is
       
   400         argument_name_path = argument.name.split(".")
       
   401         searchValue = lastKnownConfig
       
   402         while argument_name_path:
       
   403             if searchValue:
       
   404                 searchValue = searchValue.get(argument_name_path.pop(0), None)
       
   405             else:
       
   406                 break
       
   407         return searchValue
   369 
   408 
   370 
   409 
   371 def wampConfig(**kwargs):
   410 def wampConfig(**kwargs):
   372     secretfile_field = kwargs["secretfile"]
   411     secretfile_field = kwargs["secretfile"]
   373     if secretfile_field is not None:
   412     if secretfile_field is not None:
   376             secret = secretfile_field.file.read()
   415             secret = secretfile_field.file.read()
   377             SetWampSecret(secret)
   416             SetWampSecret(secret)
   378 
   417 
   379     newConfig = lastKnownConfig.copy()
   418     newConfig = lastKnownConfig.copy()
   380     for argname in webExposedConfigItems:
   419     for argname in webExposedConfigItems:
       
   420         # Check if name is composed with an intermediate dot symbol and go deep in lastKnownConfig if it is
       
   421         #  and then set a new value.
       
   422         argname_path = argname.split(".")
       
   423         arg_last = argname_path.pop()
   381         arg = kwargs.get(argname, None)
   424         arg = kwargs.get(argname, None)
   382         if arg is not None:
   425         if arg is not None:
   383             newConfig[argname] = arg
   426             tmpConf = newConfig
       
   427             while argname_path:
       
   428                 tmpConf = tmpConf.setdefault(argname_path.pop(0), {})
       
   429             tmpConf[arg_last] = arg
   384 
   430 
   385     SetConfiguration(newConfig)
   431     SetConfiguration(newConfig)
   386 
   432 
   387 
   433 
   388 class FileUploadDownload(annotate.FileUpload):
   434 class FileUploadDownload(annotate.FileUpload):
   425     ("active",
   471     ("active",
   426      annotate.Boolean(label=_("Enable WAMP connection"),
   472      annotate.Boolean(label=_("Enable WAMP connection"),
   427                       default=wampConfigDefault)),
   473                       default=wampConfigDefault)),
   428     ("url",
   474     ("url",
   429      annotate.String(label=_("WAMP Server URL"),
   475      annotate.String(label=_("WAMP Server URL"),
   430                      default=wampConfigDefault))]
   476                      default=wampConfigDefault)),
   431 
   477     ("clientFactoryOptions.maxDelay",
       
   478      annotate.Integer(label=_("Max reconnection delay (s)"),
       
   479                       default=wampConfigDefault)),
       
   480     ("protocolOptions.autoPingInterval",
       
   481      annotate.Integer(label=_("Auto ping interval (s)"),
       
   482                       default=wampConfigDefault)),
       
   483     ("protocolOptions.autoPingTimeout",
       
   484      annotate.Integer(label=_("Auto ping timeout (s)"),
       
   485                       default=wampConfigDefault))
       
   486     ]
   432 
   487 
   433 def deliverWampSecret(ctx, segments):
   488 def deliverWampSecret(ctx, segments):
   434     # filename = segments[1].decode('utf-8')
   489     # filename = segments[1].decode('utf-8')
   435 
   490 
   436     # FIXME: compare filename to ID+".secret"
   491     # FIXME: compare filename to ID+".secret"