Twisted使用

Twisted是历史悠久的开发框架,reactor的事件驱动是它的优点。
网上查阅中,很多都是直接进行调用,继承然后重写方法。但是在实际工程中,很少会通过继承的方式去继承使用一个框架。同样也不可以通过构造函数额方式传进去。假设我们要使用的框架是class B,我们要新建一个class A,当然这个类中不传入任何参数,直接在里面进行对B的调用。在A中封装好我们要实现的功能函数,然后在主函数中,首先实例化一个A,然后再调用A即可。以下是Python中Twisted的代码。

#coding:UTF-8
import os
import twisted
import twisted.internet.protocol
import twisted.internet.reactor #触发器
import twisted.internet.task
from utils1.Logger import Log
# from CatchPicture import CsiCatchPicture
from utils1.ReadConfig import Con
from CatchPicture import DelPicture
from time import sleep
from utils1 import date
logger = Log('Client_twisted').getlog()
SERVER_HOST = "192.168.155.1"  #服务主机
SERVER_PORT = int(23456)   #连接端口号
import twisted.internet.protocol
'''

A 自己的 功能与客户端连接

用Protocol实例化对象 声明 变量,


三各类,A,B,C(主函数) 主函数要调用b(相当于框架),a(自己定义的),在a里面声明b的变量,在b里面有方法,C里面实例化a,a去调B。


类和类之间,一般不是构造函数的调用的,不在构造类的时候传类的实例,一般都用组合。不能用继承


两个类之间互相调用,不要通过传参,在一个类


搜索:python之间类和类的组合调用

'''

class A(): # =mytwisted
    def __init__(self):
        self.home=B('skt').p()+'s'
    def pr(self):
        print(self.home)
class B(object):#twisted
    def __init__(self,name):
        self.name = name
    def p(self):
        return str(self.name)


SERVER_HOST = "192.168.191.1"  # 服务主机
SERVER_PORT = int(23456)  # 连接端口号


class MyTwisted():
    def __init__(self):
        pass
        # self.myprotocol= twisted.internet.protocol.Protocol()
        # self.myfactory=twisted.internet.protocol.ClientFactory()

    #设置twisted相关数据
    def SettingTwisted(self):#设置twisted相关
        self.myprotocol= twisted.internet.protocol.Protocol
        self.myprotocol.transport = twisted.internet.protocol.ProtocolToConsumerAdapter  # 调用,使transport可以有write方法进行数据传输

        self.myfactory=twisted.internet.protocol.ClientFactory
        self.myfactory.protocol = self.myprotocol




        '''---------------设置函数-------------------------------'''
        self.myfactory.clientConnectionLost = self.clientConnectionLost
        self.myfactory.clientConnectionFailed = self.clientConnectionFailed
        # 下行:自己写类,进行覆盖。设置transport属性,并调用connectionMade()回调。
        self.myprotocol.makeConnection = self.makeConnection
        self.myprotocol.connectionMade=self.connectionMade #自己写类,进行覆盖 ,此函数在连接时运行
        self.myprotocol.dataReceived = self.dataReceived

    retries = 0
    _callID = None
    connector = None
    clock = None
    delay = 5 #设定尝试重新连接的秒数
    '''----------------连接失败时执行的函数---------------------------'''
    def clientConnectionFailed(self, connector, reason):
        self.connector = connector
        print("连接失败,尝试重新连接")
        self.retry()

    '''----------------连接失去时执行的函数---------------------------'''
    def clientConnectionLost(self, connector, unused_reason):
        while connector :
            self.connector = connector
            print("失去连接,尝试重新连接")
            self.retry()
            if connector is not None:
                break

    '''----------------重试连接---------------------------'''
    def retry(self, connector=None):
        if connector is None:
            if self.connector is None:
                raise ValueError("no connector to retry")
            else:
                connector = self.connector

        self.retries += 1
        print("第"+str(self.retries)+"次尝试重新连接...")

        def reconnector():
            self._callID = None
            connector.connect()
        if self.clock is None:
            from twisted.internet import reactor
            self.clock = reactor
        self._callID = self.clock.callLater(self.delay, reconnector)


    '''-------连接服务器,调用reactor----'''
    def connect(self):
        self.SettingTwisted()
        import twisted.internet.reactor  # 触发器
        twisted.internet.reactor.connectTCP(SERVER_HOST, SERVER_PORT, self.myfactory())  # 连接服务器
        twisted.internet.reactor.run()  # 程序运行


    '''-----------------------此函数用来设置transport属性,回调connectionMade()-------------'''
    connected = 0
    transport = None

    def makeConnection(self,transport):
        """
        Make a connection to a transport and a server.

        This sets the 'transport' attribute of this Protocol, and calls the
        connectionMade() callback.
        """
        self.myprotocol.connected = 1
        self.myprotocol.transport = transport
        self.myprotocol.connectionMade()

    '''----------连接上函数时执行-----------------------'''
    def connectionMade(self):
        print("连接数据库成功...")
        logger.info("Connetcion is successful...")
        print("服务器连接成功,可以进行数据交互...")
        # logger.info("本机:和主机:连接成功")
        # self.send() # 建立简介后就进行数据的发送
        # print("服务器IP:"+str(self.transport.getHost()))
        # print("客户端IP:"+str(self.transport.getPeer()))
        # self.printhe()
        # self.send_databag()
        # self.send_picture()
        # 创建定时任务,定时循环调用

        # # sleep(2)
        # task2 = twisted.internet.task.LoopingCall(self.TakeAndSendPicture) #定时拍照,并上传,此处应有一个图像识别
        # task2.start(80) #yi个小时
        sleep(1.5)
        task1 = twisted.internet.task.LoopingCall(self.send_databag)  # 定时发送数据包
        ##开启定时任务,并指定定时任务的时间间隔
        task1.start(2)  # 0.5个小时

        # sleep(1.5)
        # task3 = twisted.internet.task.LoopingCall(self.DelPicture)  # 定时拍照,并上传,此处应有一个图像识别
        # task3.start(3600)#24个小时

        # task3 = twisted.internet.task.LoopingCall(DelPicture.delpicture)#定时删除
        # task3.start(72000)

    def dataReceived(self, data):  # 接收服务端数据
        print(data.decode("UTF-8"))  # 输出接收到的数据
        # self.send_databag() #继续发送数据

    # def send_picture(self, date):  # 发送图片,按照固定的检索目录
    #     picture_path = CsiCatchPicture.GetPicturePath() + str(date) + '.jpg'
    #     while 1:
    #         filepath = picture_path
    #         if os.path.isfile(filepath):
    #             fp = open(filepath, 'rb')
    #             while 1:
    #                 data = fp.read(1024)
    #                 if not data:
    #                     logger.info(filepath + " is send over.")
    #                     break
    #                 self.transport.write(data)
    #             # self.transport.loseConnection()  # 关闭连接
    #             sleep(2)
    #         else:
    #             logger.error("can not find the file...")
    #         break

    def send(self):  # 数据发送,自定义的方法
        input_data = input("请输入要发送的数据:")
        if input_data:  # 有输入内容
            self.transport.write(input_data.encode("UTF-8"))
        else:  # 没有有输入内容表示操作结束
            self.transport.loseConnection()  # 关闭连接

    # def TakeAndSendPicture(self):  # 封装的函数:先照相再发照片
    #
    #     date1 = CsiCatchPicture.TakePhoto(date.GetDate()[0])
    #     sleep(5)
    #     self.send_picture(date1)

    # def DelPicture(self):  # 执行此函数,如果没有目录的话,os.remove失败,整个系统会直接弹出
    #     DelPicture.delpicture()
    #     logger.info("执行删除照片函数结束")

    def send_databag(self):  # 发送数据包
        # self.connected
        databag = ''
        begin_flag = '<'
        end_flag = '>'
        brace1 = '{'
        brace2 = '}'
        machine_code = 'BM000001'  # 机器编码 算上括号 10 byte
        elect = 'DL12.5'  # 电量 算上括号 8 byte
        temper = 'WD+100.3'  # 温度 算上括号 10 byte
        humidity = 'SD100'  # 湿度 算上括号 7 byte
        SIMID = 'SMXXXXX'  # SIM卡号 算上括号 24 byte
        Motor_state = 'DJ00'  # 电机状态 算上括号 6 byte
        weight = 'ZL9999'  # 重量 算上括号 8 byte
        IP = 'IP' + self.myprotocol.transport.getHost().host  # IP地址  不定长,getsockname()函数[1]是端口号
        GPS = 'JW,V,,,,,,,,,,N*XX'  # GPS地址    不定长
        databag = databag + begin_flag + brace1 + machine_code + brace2 + brace1 + elect + brace2 + brace1 + temper + brace2 + brace1 + humidity + \
                  brace2 + brace1 + SIMID + brace2 + brace1 + Motor_state + brace2 + \
                  brace1 + weight + brace2 + brace1 + IP + brace2 + brace1 + GPS + brace2 + end_flag
        '''-----------socket发送数据-------------'''
        try:
            # 有输入内容
            self.myprotocol.transport.write(databag.encode("UTF-8"))
            sleep(2)
            # 没有有输入内容表示操作结束
            # self.transport.loseConnection()  # 关闭连接
        except:
            logger.error("The databag send to Client is fail")
        else:
            logger.info("The databag send to Client is success")
        # print("databag send over...")


if __name__ == '__main__':
    # a=A()
    # a.pr()
    b=MyTwisted()#实例化
    b.connect()#调用函数
    print("hello")
加粗样式

当然,twisted框架中很多事件函数,比如connectionMade,connectLost等,不用继承的话我们要在class A中写一个函数,然后用=替换即可。详情请见代码。如有错误,希望你能私信给我改正,谢谢。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值