Edouard@1439: #!/usr/bin/env python Edouard@1439: # -*- coding: utf-8 -*- Edouard@1439: andrej@1667: # This file is part of Beremiz runtime. andrej@1511: # andrej@1511: # Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD andrej@1511: # andrej@1667: # See COPYING.Runtime file for copyrights details. andrej@1511: # andrej@1667: # This library is free software; you can redistribute it and/or andrej@1667: # modify it under the terms of the GNU Lesser General Public andrej@1667: # License as published by the Free Software Foundation; either andrej@1667: # version 2.1 of the License, or (at your option) any later version. andrej@1667: andrej@1667: # This library is distributed in the hope that it will be useful, andrej@1511: # but WITHOUT ANY WARRANTY; without even the implied warranty of andrej@1667: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU andrej@1667: # Lesser General Public License for more details. andrej@1667: andrej@1667: # You should have received a copy of the GNU Lesser General Public andrej@1667: # License along with this library; if not, write to the Free Software andrej@1667: # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA andrej@1511: Edouard@1439: import sys Edouard@1439: from autobahn.twisted import wamp Edouard@1439: from autobahn.twisted.websocket import WampWebSocketClientFactory, connectWS Edouard@1440: from twisted.internet.defer import inlineCallbacks Edouard@1439: from autobahn.wamp import types Edouard@1440: from autobahn.wamp.serializer import MsgPackSerializer Edouard@1441: from twisted.internet.protocol import ReconnectingClientFactory Edouard@1439: import json Edouard@1439: Edouard@1439: _WampSession = None Edouard@1439: _PySrv = None Edouard@1439: Edouard@1440: ExposedCalls = ["StartPLC", Edouard@1440: "StopPLC", Edouard@1440: "ForceReload", Edouard@1440: "GetPLCstatus", Edouard@1440: "NewPLC", Edouard@1440: "MatchMD5", Edouard@1440: "SetTraceVariablesList", Edouard@1440: "GetTraceVariables", Edouard@1440: "RemoteExec", Edouard@1440: "GetLogMessage", Edouard@1441: "ResetLogCount", Edouard@1440: ] Edouard@1440: Edouard@1446: SubscribedEvents = [] Edouard@1446: Edouard@1446: DoOnJoin = [] Edouard@1446: andrej@1736: Edouard@1445: def GetCallee(name): Edouard@1446: """ Get Callee or Subscriber corresponding to '.' spearated object path """ Edouard@1440: global _PySrv Edouard@1445: names = name.split('.') Edouard@1445: obj = _PySrv.plcobj andrej@1756: while names: andrej@1756: obj = getattr(obj, names.pop(0)) Edouard@1445: return obj Edouard@1440: andrej@1736: Edouard@1439: class WampSession(wamp.ApplicationSession): Edouard@1440: Edouard@1440: @inlineCallbacks Edouard@1439: def onJoin(self, details): Edouard@1439: global _WampSession Edouard@1439: _WampSession = self Edouard@1443: ID = self.config.extra["ID"] Edouard@1443: print 'WAMP session joined by :', ID Edouard@1440: for name in ExposedCalls: andrej@1740: reg = yield self.register(GetCallee(name), '.'.join((ID, name))) Edouard@1439: Edouard@1446: for name in SubscribedEvents: Edouard@1446: reg = yield self.subscribe(GetCallee(name), name) Edouard@1446: Edouard@1446: for func in DoOnJoin: Edouard@1446: yield func(self) Edouard@1446: Edouard@1439: def onLeave(self, details): Edouard@1439: global _WampSession Edouard@1439: _WampSession = None Edouard@1439: print 'WAMP session left' Edouard@1439: andrej@1736: Edouard@1441: class ReconnectingWampWebSocketClientFactory(WampWebSocketClientFactory, ReconnectingClientFactory): Edouard@1441: def clientConnectionFailed(self, connector, reason): Edouard@1441: print("WAMP Client connection failed .. retrying ..") Edouard@1441: self.retry(connector) andrej@1751: Edouard@1441: def clientConnectionLost(self, connector, reason): Edouard@1441: print("WAMP Client connection lost .. retrying ..") Edouard@1441: self.retry(connector) Edouard@1441: andrej@1736: Edouard@1446: def LoadWampClientConf(wampconf): Edouard@1446: Edouard@1446: WSClientConf = json.load(open(wampconf)) Edouard@1446: return WSClientConf Edouard@1446: andrej@1736: Edouard@1439: def RegisterWampClient(wampconf): Edouard@1439: Edouard@1446: WSClientConf = LoadWampClientConf(wampconf) Edouard@1439: andrej@1753: # start logging to console Edouard@1440: # log.startLogging(sys.stdout) Edouard@1439: Edouard@1440: # create a WAMP application session factory Edouard@1439: component_config = types.ComponentConfig( andrej@1744: realm=WSClientConf["realm"], andrej@1744: extra={"ID": WSClientConf["ID"]}) Edouard@1439: session_factory = wamp.ApplicationSessionFactory( andrej@1744: config=component_config) Edouard@1439: session_factory.session = WampSession Edouard@1439: Edouard@1440: # create a WAMP-over-WebSocket transport client factory Edouard@1441: transport_factory = ReconnectingWampWebSocketClientFactory( Edouard@1439: session_factory, andrej@1744: url=WSClientConf["url"], andrej@1744: serializers=[MsgPackSerializer()], andrej@1744: debug=False, andrej@1744: debug_wamp=False) Edouard@1439: Edouard@1440: # start the client from a Twisted endpoint Edouard@1439: conn = connectWS(transport_factory) andrej@1740: print "WAMP client connecting to :", WSClientConf["url"] Edouard@1439: return conn Edouard@1439: andrej@1736: Edouard@1439: def GetSession(): Edouard@1439: global _WampSession Edouard@1439: return _WampSession Edouard@1439: andrej@1736: Edouard@1439: def SetServer(pysrv): Edouard@1439: global _PySrv Edouard@1439: _PySrv = pysrv