Twisted - 将数据从服务器发送到客户端
我是 Twisted 的新手,并且阅读了许多与我遇到的问题类似的相关帖子。但是,我无法推断以前的答案来解决我的简单问题。我确实参考了 Twisted 的常见问题解答部分 - 我仍然不明白。
我的问题是,我有一台服务器在一个端口侦听,当我收到“START”命令时,我想与多个客户端通信。举个例子,我使用了一个客户端,它为我提供了幸运饼干。但是,我无法在服务器代码中与客户端通信。你能告诉我哪里出错了吗?这是代码:
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()
I am new to Twisted, and have read many related posts similar to the problem that I have. 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.
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. 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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在这里,您将
self.otherFact.protocol
设置为EchoClient
类。在这里,您将
EchoClient
类 添加到self.factory.clients
列表中。这只会导致self.factory.clients
一遍又一遍地成为一个充满EchoClient
class 的列表。在这里,您尝试写入
EchoClient.transport
,它通常为None
,因为它只是连接到传输的协议类的实例,而不是类本身。尝试将连接的实例添加到 self.factory.clients 中。我认为您正在设法创建这样的实例,因为您在
FakeTelnet.connectionMade
中也有这一行:但是,您没有做任何事情来让您将连接的协议放入
self.factory.clients 列表。也许您可以这样定义
self.otherFact
:您还希望在某个时候从
clients
列表中删除内容。也许在协议的connectionLost
回调中:最后,您可能希望使用
twisted.protocols.basic.LineOnlyReceiver
作为FakeTelnet
的基类如果您正在处理面向行的数据,请将您的逻辑放入其lineReceived
回调中。dataReceived
回调不保证数据边界,因此您可能永远不会看到包含"START"
的单个字符串。例如,您可能会收到两次对dataReceived
的调用,一次调用"ST"
,另一次调用"ART"
。Here, you set
self.otherFact.protocol
to be theEchoClient
class.Here you add the
EchoClient
class to theself.factory.clients
list. This can only causeself.factory.clients
to be a list full of theEchoClient
class over and over again.Here you try to write to
EchoClient.transport
which will generally beNone
, since it is only ever instances of a protocol class which get connected to a transport, not the classes themselves.Try adding connected instances to
self.factory.clients
instead. You are managing to create such instances, I think, since you also have this line inFakeTelnet.connectionMade
:However, you aren't doing anything that would let you get the connected protocol into the
self.factory.clients
list. Perhaps you could defineself.otherFact
like this instead:You will also want to remove things from the
clients
list at some point. Perhaps in theconnectionLost
callback of the protocol:Finally, you may want to use
twisted.protocols.basic.LineOnlyReceiver
as the base class forFakeTelnet
and put your logic in itslineReceived
callback, if you are dealing with line-oriented data. ThedataReceived
callback does not make guarantees about data boundaries, so you may never see a single string containing"START"
. For example, you might get two calls todataReceived
, one with"ST"
and the other with"ART"
.