def StartGRpcServer(sJsonRpcHostPort, sModule, cnMaster, cnWorker): from gevent.event import Event from grpc import RpcServer lsHP = sJsonRpcHostPort.split(':') if len(lsHP) < 2: PrintTimeMsg("sJsonRpcHostPort=(%s) error!" % sJsonRpcHostPort) return endpoint = (lsHP[0], int(lsHP[1])) try: #WeiYF.20150414 经测试,采用importModuleClass才行 #classMaster = eval("CMaster") #eval(cnMaster) #classWorker = eval(cnWorker) # classMaster = importClassString("grcs.grsVtrbtctx.CMaster") # classWorker = importClassString("grcs.grsVtrbtctx.CWorker") classMaster = importModuleClass(sModule, cnMaster) classWorker = importModuleClass(sModule, cnWorker) master = classMaster(endpoint) svr = RpcServer() svr.bind(endpoint) t1 = classWorker() svr.register(t1) svr.register(master) t1.set_master(svr.get_export_proxy(master)) svr.start() PrintTimeMsg('Starting GRPC server(%s,%s)...' % (sModule, sJsonRpcHostPort)) wait = Event() wait.wait() #except KeyboardInterrupt: except Exception, e: import traceback traceback.print_exc() #WeiYF.20151022 打印异常整个堆栈 这个对于动态加载非常有用 PrintTimeMsg('StartGRpcServer.Exception.e=(%s)' % (str(e)))
def LoopRunRpcServer(sCallType, sHostPort, sServSeq, sPythonDir=''): """ 启动远程服务,支持如下两种协议形式 :param sCallType: JsonRPC/ZmqRPC :param sHostPort: 服务守护的IP和PORT :param sServSeq: 服务序号标识串 :param sPythonDir: CmdHandle 脚本所在路径,要带上最后的路径分隔符 :return: 无 """ lsServ = sServSeq.split('.') if len(lsServ) < 2: PrintTimeMsg("LoopRunRpcServer.sServSeq=(%s)Error,EXIT!" % (sServSeq)) sys.exit(-1) lsHP = sHostPort.split(':') if len(lsHP) < 2: PrintTimeMsg("LoopRunRpcServer.sHostPort=(%s)Error,EXIT!" % (sHostPort)) sys.exit(-1) sHost = lsHP[0] if sHost != '127.0.0.1': #WeiYF.20151026 非127.0.0.1则是0.0.0.0 sHost = '0.0.0.0' sHostPort = '%s:%s' % (sHost, lsHP[1]) if sCallType[:1] == 'Z': # JsonRPC/ZmqRPC from WyfZmqCmdFuncs import LoopRunExecZmqCmdReply LoopRunExecZmqCmdReply(sHostPort, sServSeq, sPythonDir) else: # from WyfPublicFuncs import importModuleClass,LoopRunExecJsonRpcServer CmdHandleStandard = importModuleClass( sPythonDir + 'CmdHandle' + lsServ[0], 'CmdHandleStandard') m = CmdHandleStandard([sServSeq]) setattr(m, 'sServ', lsServ[0]) LoopRunJsonRpcServer(sHostPort, sServSeq, GenJsonRpcReqHandlerClass(m))
def __SendCustomMsg(self, sOpenId, sMsg): # 参见 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140547&token=&lang=zh_CN # http请求方式: POST # https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN # 发送客服消息 # self.sAccessToken = 'bc3_B_Fqtsy0gtSwLsVSikWmKx2epGVo1k10YjycsODhL8Kvlp8s2QwW9GLp9y0PCbc9sKNa5n9XKHIegBu0tphuKphCYhJGaoMWzteihah0KasuO5j0E3A4hBOktfzqOIEiACAXRN' sUrl = self.__getWxUrl('message/custom/send?access_token=%s' % self.sAccessToken) dictData = { "touser": sOpenId, "msgtype": "text", "text": { "content": sMsg, } } sData = json.dumps(dictData,ensure_ascii=False) sRet = HttpPostJson(sUrl,sData) #RequestsHttpPost # sRet = RequestsHttpPost(sUrl,dictData) #使用该函数会出错 jsonRet = json.loads(sRet) errcode = jsonRet.get('errcode',0) if errcode==0: PrintTimeMsg('__SendCustomMsg(%s)=OK!' % sOpenId) else: errmsg = jsonRet.get('errmsg','@DefaultError') PrintTimeMsg('__SendCustomMsg(%s)=Error(%s,%s)!' % (sOpenId,errcode,errmsg)) return errcode
def __init__(self, sSMTPHost, sAccoutFull, sPassword): self.sSMTPHost = sSMTPHost self.sAccoutFull = sAccoutFull self.sPassword = sPassword (self.sAccout, cSep, self.sMailHost) = self.sAccoutFull.partition('@') if cSep == '': PrintTimeMsg("CSendSMTPMail.sAccoutFull=%s,Error To EXIT!" % (self.sAccoutFull)) sys.exit(-1) PrintTimeMsg("CSendSMTPMail.sSMTPHost=%s,sAccoutFull=%s!" % (self.sSMTPHost, self.sAccoutFull))
def __sendMail(self, sToEMail, sSubject, sContent, sFromTitle): """ 发送邮件 :param sToEMail: 目标email,多个email可以采用英文分号分开 :param sSubject: 邮件主题,utf-8编码 :param sContent: 邮件内容,utf-8编码 :param sFromTitle: 发件人名称,utf-8编码 :return: 无 """ # print 'sFromTitle', sFromTitle msg = MIMEMultipart() msg['From'] = sFromTitle.decode('utf-8').encode( "gbk", "ignore") + "<%s>" % (self.sAccoutFull) # sSubject = sSubject.decode('utf-8').encode("gbk", "ignore") sContent = sContent.decode('utf-8').encode("gbk", "ignore") msg['Subject'] = sSubject #.encode("gbk","ignore") txt = MIMEText(sContent, 'html', 'gbk') msg.attach(txt) # send email if self.sMailHost.upper() in ['QQ.COM']: #QQ邮箱要采用SSL登录 smtp = smtplib.SMTP_SSL('smtp.qq.com', timeout=30) #连接smtp邮件服务器,端口默认是25 else: smtp = smtplib.SMTP(self.sSMTPHost) # smtp.set_debuglevel(1) #会打印邮件发送日志 smtp.login(self.sAccout, self.sPassword) for sTo in sToEMail.split(';'): if sTo: smtp.sendmail(self.sAccoutFull, sTo, msg.as_string()) smtp.quit() PrintTimeMsg('SendMail.sToEMail(%s) successfully!' % sToEMail)
class CAutoConnectRedis: def __init__(self, sClientName): self.sClientName = sClientName self.dictRedisByParam = {} def GetRedis(self, sRedisParam): dictRedis = self.dictRedisByParam.get(sRedisParam, {}) oRedis = dictRedis.get('oRedis', None) bNeedNew = not oRedis try: if oRedis: oRedis.incr('KV_COUNT_COMMAND_%s' % self.sClientName) dictRedis['tmLastCommand'] = time.time() except Exception, e: #ConnectionError TimeoutError import traceback traceback.print_exc() #WeiYF.20151022 打印异常整个堆栈 这个对于动态加载非常有用 PrintTimeMsg('GetRedis.COMMAND.Exception.e=(%s)' % (str(e))) bNeedNew = True if bNeedNew: try: oRedis = GetRedisClient(sRedisParam) oRedis.incr('KV_COUNT_CONNECT_%s' % self.sClientName) dictRedis['oRedis'] = oRedis dictRedis['tmLastConnect'] = time.time() self.dictRedisByParam[sRedisParam] = dictRedis except Exception, e: #ConnectionError TimeoutError import traceback traceback.print_exc() #WeiYF.20151022 打印异常整个堆栈 这个对于动态加载非常有用 PrintTimeMsg('GetRedis.CONNECT.Exception.e=(%s)' % (str(e))) return None
def GetGRpcClient(sJsonRpcHostPort, server_id): from grpc import get_proxy_by_addr lsHP = sJsonRpcHostPort.split(':') if len(lsHP) < 2: PrintTimeMsg("sJsonRpcHostPort=(%s) error!" % sJsonRpcHostPort) return endpoint = (lsHP[0], int(lsHP[1])) return get_proxy_by_addr(endpoint, server_id)
def __init__(self, sServSeq, sPythonDir): lsSS = sServSeq.split('.') if len(lsSS) < 2: PrintTimeMsg("ZmqCmdReply.sServSeq=(%s)Error,EXIT!" % (sServSeq)) sys.exit(-1) self.sServ = lsSS[0] self.sServSeq = sServSeq self.sPythonDir = sPythonDir
def GetRedisClient(sRedisParam): import redis # sRedisParam = '192.168.2.209:6379:6' # sRedisParam = '192.168.2.209:6379:6:password' sPassword = None # WeiYF.20160414 Redis参数支持密码 lsP = sRedisParam.split(':') if len(lsP) < 3: PrintTimeMsg("GetRedisClient.sRedisParam=(%s)=Error,EXIT!" % (sRedisParam)) sys.exit(-1) if len(lsP) >= 4: sPassword = lsP[3] oRedis = redis.StrictRedis(host=lsP[0], port=int(lsP[1]), db=int(lsP[2]), password=sPassword, socket_timeout=30) #WeiYF.20160606 新增超时参数 PrintTimeMsg("GetRedisClient(%s)ReturnOK..." % (sRedisParam)) return oRedis
def __init__(self, callBackDealOne): if not callBackDealOne: PrintTimeMsg('CThreadCacheByQueue.callBackDealOne=None,EXIT!') sys.exit(-1) self.callBackDealOne = callBackDealOne self.iDealCount = 0 self.bLoopRunFlag = True self.queue = Queue() StartThreadDoSomething(self.ftCallBackForPush)
def __init__(self, callBackDealOne): if not callBackDealOne: PrintTimeMsg('CThreadDiscardDeal.callBackDealOne=None,EXIT!') sys.exit(-1) self.callBackDealOne = callBackDealOne self.bLoopRunFlag = True self.mutex = Lock() self.dictDealFlag = {} StartThreadDoSomething(self.ftCallBackForPush)
def LoopRunJsonRpcServer(sHostPort, sServSeq, ReqHandlerClass): import pyjsonrpc PrintTimeMsg('LoopRunJsonRpcServer.sHostPort=(%s),sServSeq=(%s)...' % (sHostPort, sServSeq)) lsHP = sHostPort.split(':') if len(lsHP) < 2: PrintTimeMsg("hpHostPort=(%s)Error,should (IP:PORT)fmt! EXIT!" % hpHostPort) sys.exit(-101) return # Threading HTTP-Server http_server = pyjsonrpc.ThreadingHttpServer( server_address=(lsHP[0], int(lsHP[1])), RequestHandlerClass=ReqHandlerClass) PrintTimeMsg('Start JsonRpcServer http://%s ...' % (sHostPort)) try: http_server.serve_forever(poll_interval=0.01) except KeyboardInterrupt: http_server.shutdown() PrintTimeMsg('Stop JsonRpcServer http://%s !!!' % (sHostPort))
def __getToken(self): sParam = 'grant_type=client_credential&appid=%s&secret=%s' % (self.sAPPID, self.sAPPSECRET) sUrl = self.__getWxUrl('token?%s' % sParam) sRet = HttpGet(sUrl) # print ("Get(%s)=(%s)" % (sUrl,sRet)) if sRet: jsonDict = json.loads(sRet) if jsonDict: self.sAccessToken = jsonDict.get("access_token","") if self.sAccessToken=="": PrintTimeMsg("__getToken=(%s)error" % (str(jsonDict))) else: self.iTmTokenExpire = time.time()+int(jsonDict.get("expires_in","0")) PrintTimeMsg("__getToken.expires_time=(%s)" % (time.strftime( "%Y%m%d-%H%M%S",time.localtime(self.iTmTokenExpire)) )) # print "self.access_token=",self.access_token else: PrintTimeMsg("__getToken=(%s)error" % (str(jsonDict))) else: PrintTimeMsg("__getToken=None")
def GetRedis(self, sRedisParam): dictRedis = self.dictRedisByParam.get(sRedisParam, {}) oRedis = dictRedis.get('oRedis', None) bNeedNew = not oRedis try: if oRedis: oRedis.incr('KV_COUNT_COMMAND_%s' % self.sClientName) dictRedis['tmLastCommand'] = time.time() except Exception, e: #ConnectionError TimeoutError import traceback traceback.print_exc() #WeiYF.20151022 打印异常整个堆栈 这个对于动态加载非常有用 PrintTimeMsg('GetRedis.COMMAND.Exception.e=(%s)' % (str(e))) bNeedNew = True
def LoadClassFromFile(sPythonFName, sExpectedClass, *args): # 从指定Python文件中,动态加载指定类 import os import imp try: instClass = None mod_name, file_ext = os.path.splitext(os.path.split(sPythonFName)[-1]) if file_ext.lower() == '.py': py_mod = imp.load_source(mod_name, sPythonFName) elif file_ext.lower() == '.pyc': py_mod = imp.load_compiled(mod_name, sPythonFName) if hasattr(py_mod, sExpectedClass): # instClass = getattr(py_mod, sExpectedClass)(args) #WeiYF.20151022 没有*,会多包括括号,多一层tuple instClass = getattr(py_mod, sExpectedClass)(*args) #WeiYF.20151022 应该加上* except Exception, e: PrintTimeMsg('LoadClassFromFile(%s)=(%s)' % (sPythonFName, str(e))) raise #Using raise with no arguments re-raises the last exception
def CallCmd(self, sServ, sFuncName, lsParam): #WeiYF.20151020 调用时直接给出函数名,无需添加服务前缀;加了反而不行 # PrintTimeMsg("CallCmd.sServ=(%s)!" % (sServ)) #通过参数直接传入了 # WeiYF.20151022 通过如下方法也可以取到对象的附加属性 # sServAttr = '' # if hasattr(oCmdHandleStandard,'sServ'): sServAttr = oCmdHandleStandard.sServ # PrintTimeMsg("CallCmd.sServAttr=(%s)!" % (sServAttr)) CmdIStr = [sServ + '.' + sFuncName] CmdIStr.extend(lsParam) # PrintTimeMsg('CallCmd(%s,%s)...' % (sFuncName, CmdIStr)) try: PrintMsTimeMsg("CallByName(%s)..." % sFuncName) oRet = oCmdHandleStandard.CallByName(sFuncName, CmdIStr) PrintMsTimeMsg("CallByName(%s)!!!" % sFuncName) except Exception, e: import traceback traceback.print_exc() #WeiYF.20151022 打印异常整个堆栈 这个对于动态加载非常有用 PrintTimeMsg('CallCmd.Exception.e=(%s)' % (str(e)))
def cbTest(sKey, iDealFlag): PrintTimeMsg('cbTest.sKey=%s,iDealFlag=%s=' % (sKey, iDealFlag))
svr.register(master) t1.set_master(svr.get_export_proxy(master)) svr.start() PrintTimeMsg('Starting GRPC server(%s,%s)...' % (sModule, sJsonRpcHostPort)) wait = Event() wait.wait() #except KeyboardInterrupt: except Exception, e: import traceback traceback.print_exc() #WeiYF.20151022 打印异常整个堆栈 这个对于动态加载非常有用 PrintTimeMsg('StartGRpcServer.Exception.e=(%s)' % (str(e))) finally: #svr.stop() pass PrintTimeMsg('Stopping GRPC server(%s,%s)!!!' % (sModule, sJsonRpcHostPort)) #------------------------------------------------------- def LoadClassFromFile(sPythonFName, sExpectedClass, *args): # 从指定Python文件中,动态加载指定类 import os import imp try: instClass = None mod_name, file_ext = os.path.splitext(os.path.split(sPythonFName)[-1]) if file_ext.lower() == '.py': py_mod = imp.load_source(mod_name, sPythonFName) elif file_ext.lower() == '.pyc': py_mod = imp.load_compiled(mod_name, sPythonFName) if hasattr(py_mod, sExpectedClass):
def SetLoopRunFlag(self, bFlag): self.bLoopRunFlag = bFlag PrintTimeMsg('CThreadDiscardDeal.SetLoopRunFlag=(%s)!' % (self.bLoopRunFlag))
def cbTest(oData, iDealCount): PrintTimeMsg('%d#cbTest.oData=%s=' % (iDealCount, oData))
def run(self ): # Overwrite run() method, put what you want the thread do here self.ftCallBack() PrintTimeMsg('CThreadDoSomething.End!')
def SetLoopRunFlag(self, bFlag): self.bLoopRunFlag = bFlag PrintTimeMsg('CThreadCacheByQueue.SetLoopRunFlag=(%s)!' % (self.bLoopRunFlag))
def WyfCmd(self, sParam): # for test PrintTimeMsg("WyfCmd.sParam=(%s)!" % (sParam)) return '{%s}' % sParam
def __del__(self): if hasattr(self,'oRedis') and self.oRedis: self.oRedis.connection_pool.disconnect() PrintTimeMsg("CRedisSNetFuncs.disconnect()!!!")
def PrintHintMsgForReply(self,sHint,sSNetHubIdStr): PrintTimeMsg("%s.WaitForRedis.KEY=(%s)..." % (sHint,self._getKeyListSnetCmd('Reply',sSNetHubIdStr)))
def PrintHintMsgForRequest(self,sHint): PrintTimeMsg("%s.WaitForRedis.KEY=(%s)..." % (sHint,self._getKeyListSnetCmd('Request','')))