加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python – 我应该如何处理twisted.application.internet.ClientS

发布时间:2020-12-20 13:12:00 所属栏目:Python 来源:网络整理
导读:我试图在扭曲的应用程序中使用 recently introduced twisted.application.internet.ClientService 类,使用pymodbus进行简单的modbus-tcp轮询.我觉得我的问题与我正在使用的modbus协议无关,因为我使用较低级别的扭曲API创建了许多其他工作原型;但是这个新的Cl
我试图在扭曲的应用程序中使用 recently introduced twisted.application.internet.ClientService类,使用pymodbus进行简单的modbus-tcp轮询.我觉得我的问题与我正在使用的modbus协议无关,因为我使用较低级别的扭曲API创建了许多其他工作原型;但是这个新的ClientService看起来完全符合我的需求,因此应该减少我的代码占用空间并保持整洁,如果我可以让它工作.

我的测试显示ClientService正如预期的那样处理重新连接,并且我可以轻松访问第一个连接协议.我遇到的问题是为重新连接获取后续的Protocol对象.这是我遇到问题的代码的简化版本:

from twisted.application import internet,service
from twisted.internet.protocol import ClientFactory
from twisted.internet import reactor,endpoints
from pymodbus.client.async import ModbusClientProtocol

class ModbusPollingService(internet.ClientService):
    def __init__(self,addrstr,numregs=5):
        self.numregs=numregs
        internet.ClientService.__init__(self,endpoints.clientFromString(reactor,addrstr),ClientFactory.forProtocol(ModbusClientProtocol))

    def startService(self):
        internet.ClientService.startService(self)
        self._pollWhenConnected()

    def _pollWhenConnected(self):
        d = self.whenConnected()
        d.addCallback(self._connected)
        d.addErrback(self._connfail)

    def _connected(self,p):
        self._log.debug("connected: {p}",p=p)
        self._mbp = p
        self._poll()
        return True

    def _connfail(self,failstat):
        self._log.failure('connection failure',failure=failstat)
        self._mbp = None
        self._pollWhenConnected()

    def _poll(self):
        self._log.debug("poll: {n}",n=self.numregs)
        d = self._mbp.read_holding_registers(0,self.numregs)
        d.addCallback(self._regs)
        d.addErrback(self._connfail)

    def _regs(self,res):
        self._log.debug("regs: {r}",r=res.registers)
        # Do real work of dealing storing registers here
        reactor.callLater(1,self._poll)
        return res

application = service.Application("ModBus Polling Test")
mbpollsvc = ModbusPollingService('tcp:127.0.0.1:502')
mbpollsvc.setServiceParent(application)

当连接失败时(无论出于何种原因),从read_holding_registers()返回的延迟的错误被调用,意图是我的服务可以放弃该协议并返回到等待新连接的状态由whenConnected返回协议()回调…然而,似乎正在发生的事情是ClientService尚未意识到连接已经死亡并且返回了相同的断开连接的协议,给我一个完整的日志:

2016-05-05 17:28:25-0400 [-] connected: <pymodbus.client.async.ModbusClientProtocol object at 0x000000000227b558>
2016-05-05 17:28:25-0400 [-] poll: 5
2016-05-05 17:28:25-0400 [-] connection failure
    Traceback (most recent call last):
    Failure: pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Client is not connected

2016-05-05 17:28:25-0400 [-] connected: <pymodbus.client.async.ModbusClientProtocol object at 0x000000000227b558>
2016-05-05 17:28:25-0400 [-] poll: 5
2016-05-05 17:28:25-0400 [-] connection failure
    Traceback (most recent call last):
    Failure: pymodbus.exceptions.ConnectionException: Modbus Error: [Connection] Client is not connected

或者非常相似,请注意重复的ModbusClientProtocol对象地址.

我很确定我可能只是为这个API做了一个糟糕的模式选择,但我已经迭代了几个不同的可能性,比如创建我自己的基于ModbusClientProtocol的协议和工厂,并完全处理轮询机制类;但是通过持久化的配置和机制以存储轮询数据的方式感觉有点凌乱,似乎在ClientService级别或以上处理这个是一个更干净的方法,但我无法找出跟踪的最佳方法目前连接的协议.我想我真正想要的是在扩展轮询情况下使用ClientService类的最佳实践建议.

解决方法

你不是在我可以看到的任何地方调用self.transport.loseConnection()来响应你的轮询,所以只要扭曲可以告诉你,你实际上并没有断开连接.可能以后,当你停止对旧运输做任何事情时,但到那时你已经忘记了事情.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读