[英]Twisted - send data from a server to client
I am new to Twisted, and have read many related posts similar to the problem that I have.我是 Twisted 的新手,并且已经阅读了许多与我遇到的问题类似的相关帖子。 However, I am unable to extrapolate the previous answers to solve my simple problem.
但是,我无法推断以前的答案来解决我的简单问题。 I did refer to the FAQ section of Twisted - I still can't figure out.
我确实参考了 Twisted 的常见问题解答部分 - 我仍然无法弄清楚。
My problem is that I have a server listening at one port, and when I receive a "START" command, I would like to talk to several clients.我的问题是我有一台服务器在一个端口上监听,当我收到“START”命令时,我想与几个客户端交谈。 As an example, I used a single client, that serves me a fortune cookie.
例如,我使用了一个客户端,它为我提供幸运饼干。 However, I am unable to talk to client from with in the server code.
但是,我无法在服务器代码中与客户端交谈。 Can you please tell where I am going wrong?
你能告诉我哪里出错了吗? Here is the code:
这是代码:
from twisted.internet import reactor, protocol
from twisted.internet.protocol import Protocol, Factory
class FakeTelnet(Protocol):
def connectionMade(self):
print 'local connection made'
self.otherFact = protocol.ClientFactory()
self.otherFact.protocol = EchoClient
self.factory.clients.append(self.otherFact.protocol)
reactor.connectTCP('psrfb6',10999, self.otherFact)
def dataReceived(self, data):
if 'START' in data:
# send a command to cookie server.
for client in self.factory.clients:
client.transport.write('START\r\n')
def connectionLost(self):
print 'connection lost'
class EchoClient(Protocol):
"""Once connected, send a message, then print the result."""
def connectionMade(self):
print "Connection to cookie server"
def dataReceived(self, data):
"As soon as any data is received, write it back."
print "Fortune Server said:", data
def connectionLost(self):
print "connection lost"
def send_stuff(data):
self.transport.write(data);
class MyFactory(Factory):
protocol = FakeTelnet
def __init__(self, EchoClient):
self.clients = []
self.otherCli = EchoClient
reactor.listenTCP(5823, MyFactory(EchoClient))
reactor.run()
class FakeTelnet(Protocol):
def connectionMade(self):
print 'local connection made'
self.otherFact = protocol.ClientFactory()
self.otherFact.protocol = EchoClient
Here, you set self.otherFact.protocol
to be the EchoClient
class .在这里,您将
self.otherFact.protocol
设置为EchoClient
class 。
self.factory.clients.append(self.otherFact.protocol)
Here you add the EchoClient
class to the self.factory.clients
list.在这里,您将
EchoClient
class添加到self.factory.clients
列表中。 This can only cause self.factory.clients
to be a list full of the EchoClient
class over and over again.这只会导致
self.factory.clients
成为一个充满EchoClient
class的列表。
def dataReceived(self, data):
if 'START' in data:
# send a command to cookie server.
for client in self.factory.clients:
client.transport.write('START\r\n')
Here you try to write to EchoClient.transport
which will generally be None
, since it is only ever instances of a protocol class which get connected to a transport, not the classes themselves.在这里,您尝试写入通常为
None
的EchoClient.transport
,因为它只是连接到传输的协议 class 的实例,而不是类本身。
Try adding connected instances to self.factory.clients
instead.尝试将连接的实例添加到
self.factory.clients
。 You are managing to create such instances, I think, since you also have this line in FakeTelnet.connectionMade
:我认为您正在设法创建此类实例,因为您在
FakeTelnet.connectionMade
中也有这一行:
reactor.connectTCP('psrfb6',10999, self.otherFact)
However, you aren't doing anything that would let you get the connected protocol into the self.factory.clients
list.但是,您没有做任何让您将连接的协议放入
self.factory.clients
列表的事情。 Perhaps you could define self.otherFact
like this instead:也许你可以这样定义
self.otherFact
:
class OtherFactory(ClientFactory):
protocol = EchoClient
def __init__(self, originalFactory):
self.originalFactory = originalFactory
def buildProtocol(self, addr):
proto = ClientFactory.buildProtocol(self, addr)
self.originalFactory.clients.append(proto)
return proto
You will also want to remove things from the clients
list at some point.您还需要在某个时候从
clients
列表中删除某些内容。 Perhaps in the connectionLost
callback of the protocol:也许在协议的
connectionLost
回调中:
class EchoClient(Protocol):
...
def connectionLost(self, reason):
self.factory.originalFactory.clients.remove(self)
Finally, you may want to use twisted.protocols.basic.LineOnlyReceiver
as the base class for FakeTelnet
and put your logic in its lineReceived
callback, if you are dealing with line-oriented data.最后,如果您正在处理面向行的数据,您可能希望使用
twisted.protocols.basic.LineOnlyReceiver
作为 FakeTelnet 的基础FakeTelnet
并将您的逻辑放入其lineReceived
回调中。 The dataReceived
callback does not make guarantees about data boundaries, so you may never see a single string containing "START"
. dataReceived
回调不保证数据边界,因此您可能永远不会看到包含"START"
的单个字符串。 For example, you might get two calls to dataReceived
, one with "ST"
and the other with "ART"
.例如,您可能会收到两次对
dataReceived
的调用,一次使用"ST"
,另一次使用"ART"
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.