Я пишу TCP-сервер для прослушивания TCP-пакетов, содержащих информацию о состоянии с удаленных компьютеров. Удаленные машины поддерживают соединение TCP после его установления. Вот основные части моего кода:
#!/usr/bin/python
from twisted.internet import reactor, protocol
class FactoryProcess(protocol.Protocol):
def dataReceived(self, data):
# Process received data
def send_data(self, message):
# Reply to message etc
self.transport.write(message)
factory = protocol.ServerFactory()
factory.protocol = FactoryProcess
reactor.listenTCP(8256,factory)
reactor.run()
Машины могут подключаться и отправлять свои данные, а я могу отправлять подтверждения обратно в блок send_data
. Все идет нормально. Я не могу понять, как асинхронно отправлять данные на одно из устройств из-за пределов кода протокола. Очевидно, мне нужно каким-то образом получить доступ к экземпляру класса Factory для конкретного соединения, которое я хочу использовать, но я не понимаю, как это сделать. Берегите себя и большое спасибо.
РЕДАКТИРОВАТЬ После того, как @notorious.no предоставил очень полезный пример, я изменил свой код для захвата IP-адресов и портов, а также объектов подключения подключенных устройств:
from twisted.internet import endpoints, protocol, reactor
device_ips = []
device_ports = []
connections = []
class ChatProtocol(protocol.Protocol):
def connectionMade(self):
global device_ips, device_ports, connections
# Append client
self.factory.clientList.append(self)
print('client connected. Connection Count = ' + str(len(self.factory.clientList)))
connections.append(self)
ip, port = self.transport.client
device_ips.append(ip)
device_ports.append(port)
print('ips:' + str(device_ips) + ', ports:' + str(device_ports) + ', connections:' + str(connections))
def connectionLost(self, _):
# Remove client
self.factory.clientList.remove(self)
print('client lost. Connection Count = ' + str(len(self.factory.clientList)))
def dataReceived(self, data):
print('Data received:' + str(data))
# Send message to all connected clients
for client in self.factory.clientList:
if client == self:
continue
client.transport.write(data)
class ChatFactory(protocol.Factory):
protocol = ChatProtocol
clientList = []
def main():
epServer = endpoints.serverFromString(reactor, "tcp:8123")
epServer.listen(ChatFactory())
reactor.run()
main()
Когда я запускаю это, а затем подключаю два тестовых устройства, я получаю:
client connected. Connection Count = 1
ips:['redacted'], ports:[54182], connections:[<__main__.ChatProtocol instance at 0x7f5a835afcd0>]
client connected. Connection Count = 2
ips:['redacted', 'redacted'], ports:[54182, 57437], connections:[<__main__.ChatProtocol instance at 0x7f5a835afcd0>, <__main__.ChatProtocol instance at 0x7f5a835c2140>]
Итак, теперь у меня есть списки IP-адресов и портов подключенных устройств, и, предположительно, я могу использовать объекты соединений для асинхронной отправки сообщения при необходимости. Пожалуйста, не могли бы вы посоветовать, как мне это сделать? Берегите...