扭曲中的持久连接 [英] Persistent connection in twisted

查看:29
本文介绍了扭曲中的持久连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Twisted 的新手,有一个问题.如何在 Twisted 中组织持久连接?我有一个队列,每一秒都会检查它.如果有一些 - 在客户端发送.我找不到比每秒调用 dataReceived 更好的方法了.下面是协议实现的代码:

I'm new in Twisted and have one question. How can I organize a persistent connection in Twisted? I have a queue and every second checks it. If have some - send on client. I can't find something better than call dataReceived every second. Here is the code of Protocol implementation:

class SyncProtocol(protocol.Protocol):
    # ... some code here
    def dataReceived(self, data):
        if(self.orders_queue.has_new_orders()):
            for order in self.orders_queue:
                self.transport.write(str(order))

        reactor.callLater(1, self.dataReceived, data)  # 1 second delay

它按我的需要工作,但我确信这是非常糟糕的解决方案.我怎样才能以不同的方式(灵活和正确)做到这一点?谢谢.

It works how I need, but I'm sure that it is very bad solution. How can I do that in different way (flexible and correct)? Thanks.

附言- 主要思想和算法:1.客户端连接到服务器并等待2.服务器检查更新并将数据推送到客户端如果有任何变化3.客户端做一些操作,然后等待其他数据

P.S. - the main idea and alghorithm: 1. Client connect to server and wait 2. Server checks for update and pushes data to client if anything changes 3. Client do some operations and then wait for other data

推荐答案

在不知道您提供的代码段如何链接到您的 internet.XXXServerreactor.listenXXX(或XXXXEndpoint 调用),很难对它做出正面或反面,但是...

Without knowing how the snippet you provided links into your internet.XXXServer or reactor.listenXXX (or XXXXEndpoint calls), its hard to make head-or-tails of it, but...

首先,在正常使用中,扭曲的protocol.ProtocoldataReceived 只会被框架本身调用.它将直接或通过工厂链接到客户端或服务器连接,并在数据进入给定连接时自动调用.(绝大多数twisted 协议和接口(如果不是全部的话)都是基于中断的,而不是轮询/callLater,这是使Twisted 如此高效CPU 的部分原因)

First off, in normal use, a twisted protocol.Protocol's dataReceived would only be called by the framework itself. It would be linked to a client or server connection directly or via a factory and it would be automatically called as data comes into the given connection. (The vast majority of twisted protocols and interfaces (if not all) are interrupt based, not polling/callLater, thats part of what makes Twisted so CPU efficient)

因此,如果您显示的代码实际上通过 ServerlistenEndpoint 链接到 Twisted 到您的客户端,那么我想您会发现如果您的客户端发送数据,将会发生非常糟糕的事情(...因为twisted 会为此调用dataReceived,这(以及其他问题)会添加额外的reactor.callLater 回调各种混乱都会接踵而至...)

So if your shown code is actually linked into Twisted via a Server or listen or Endpoint to your clients then I think you will find very bad things will happen if your clients ever send data (... because twisted will call dataReceived for that, which (among other problems) would add extra reactor.callLater callbacks and all sorts of chaos would ensue...)

如果相反,代码没有链接到扭曲连接框架中,那么您试图在它们不是设计的空间中重用扭曲类(...我想这似乎不太可能,因为我不知道如何非- 连接代码会了解传输,除非您手动设置它...)

If instead, the code isn't linked into twisted connection framework, then your attempting to reuse twisted classes in a space they aren't designed for (... I guess this seems unlikely because I don't know how non-connection code would learn of a transport, unless your manually setting it...)

我一直在构建这样的构建模型的方式是为基于轮询的 I/O 创建一个完全独立的类,但是在我实例化它之后,我将我的客户端列表(服务器)工厂推送到轮询实例中(像 mypollingthing.servfact = myserverfactory)这样的东西-通过为我的轮询逻辑提供一种方法,以便能够调用客户端 .write(或者更可能是我构建的用于抽象到正确级别的定义)我的投票逻辑)

The way I've been build building models like this is to make a completely separate class for the polling based I/O, but after I instantiate it, I push my client-list (server)factory into the polling instance (something like mypollingthing.servfact = myserverfactory) there-by making a way for my polling logic to be able to call into the clients .write (or more likely a def I built to abstract to the correct level for my polling logic)

我倾向于将 Krondo 的 Twisted Introduction 中的示例作为如何做扭曲(其他扭曲矩阵),以及第6部分中的示例,在客户端3.0"下PoetryClientFactory 有一个 __init__ 在工厂中设置回调.

I tend to take the examples in Krondo's Twisted Introduction as one of the canonical examples of how to do twisted (other then twisted matrix), and the example in part 6, under "Client 3.0" PoetryClientFactory has a __init__ that sets a callback in the factory.

如果我尝试将其与 twistedmatrix 聊天示例和其他一些事情,我得到:(您需要将 sendToAll 更改为您的 self.orders_queue.has_new_orders() 的任何内容)

If I try blend that with the twistedmatrix chat example and a few other things, I get: (You'll want to change sendToAll to whatever your self.orders_queue.has_new_orders() is about)

#!/usr/bin/python

from twisted.internet import task
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, ServerFactory

class PollingIOThingy(object):
    def __init__(self):
        self.sendingcallback = None # Note I'm pushing sendToAll into here in main
        self.iotries = 0

    def pollingtry(self):
        self.iotries += 1
        print "Polling runs: " + str(self.iotries)
        if self.sendingcallback:
            self.sendingcallback("Polling runs: " + str(self.iotries) + "\n")

class MyClientConnections(Protocol):
    def connectionMade(self):
        print "Got new client!"
        self.factory.clients.append(self)

    def connectionLost(self, reason):
        print "Lost a client!"
        self.factory.clients.remove(self)

class MyServerFactory(ServerFactory):
    protocol = MyClientConnections

    def __init__(self):
        self.clients = []

    def sendToAll(self, message):
      for c in self.clients:
        c.transport.write(message)

def main():
    client_connection_factory = MyServerFactory()

    polling_stuff = PollingIOThingy()

    # the following line is what this example is all about:
    polling_stuff.sendingcallback = client_connection_factory.sendToAll
    # push the client connections send def into my polling class

    # if you want to run something ever second (instead of 1 second after
    # the end of your last code run, which could vary) do:
    l = task.LoopingCall(polling_stuff.pollingtry)
    l.start(1.0) 
    # from: https://twistedmatrix.com/documents/12.3.0/core/howto/time.html

    reactor.listenTCP(5000, client_connection_factory)
    reactor.run()

if __name__ == '__main__':
  main()

公平地说,最好通过将回调作为参数传递给 __init__ 来通知 PollingIOThingy 回调(这在 Krondo 的文档中显示), 出于某种原因,当我阅读代码并发现课堂作弊更容易看到时,我往往会错过这样的联系,但这可能只是我个人的脑损伤.

To be fair, it might be better to inform PollingIOThingy of the callback by passing it as an arg to it's __init__ (that is what is shown in Krondo's docs), For some reason, I tend to miss connections like this when I read code and find class-cheating easier to see, but that may just by my personal brain-damage.

这篇关于扭曲中的持久连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆