J'ai écrit une usine de serveur tcp de base, un client serveur et un service utilisant twisted. Le serveur tcp agit comme middleware entre un serveur django et un autre programme (appelons-le programme client).Impossible de faire une requête http au serveur django en utilisant twisted.web.AGENT
Ce que je veux réaliser -
1. client demande au serveur middleware tcp ;
2.it envoie une chaîne en tant que corps de requête;
3.le middleware Le serveur tcp désérialise les informations de la demande.
4. middleware fournit les informations sérialisées au serveur django.
5.Le serveur django répond alors au serveur middleware qui favorise la réponse au client après sérialisation la réponse.
Je suis capable d'atteindre jusqu'à l'étape 3, mais je suis incapable de faire une requête http au serveur django.
Ce qui suit est mon middleware.py
from twisted.internet.protocol import ServerFactory
from twisted.internet.protocol import Protocol
from test_service import MyService
class TCPServerProtocol(Protocol):
data = ''
def connectionMade(self):
self.deferred = self.factory.service.deferred
self.deferred.addCallback(self.factory.service.s)
self.deferred.addCallback(self.transport.write)
self.deferred.addBoth(lambda r: self.transport.loseConnection)
def dataReceived(self, data):
self.data += data
def connectionLost(self, reason):
self.forward(self.data)
def forward(self, data):
if self.deferred is not None:
d, self.deferred = self.deferred, None
d.callback(data)
class TCPServerFactory(ServerFactory):
protocol = TCPServerProtocol
def __init__(self, service):
self.service = service
def runserver(ip, port):
iface = {'home': '192.168.0.104', 'work': '127.0.0.1'}
service = MyService()
factory = TCPServerFactory(service)
from twisted.internet import reactor
reactor.listenTCP(port=port, factory=factory, interface=iface[ip])
reactor.run()
if __name__ == '__main__':
import sys
ip = sys.argv[1]
port = int(sys.argv[2])
runserver(ip, port)
Ce qui suit est test_service.py
from twisted.internet.defer import Deferred
from test_http_client import HTTPClientFactory
class MyService(object):
def __init__(self):
self.deferred = Deferred()
def s(self, data):
kwargs = {}
kwargs['url'] = b'http://127.0.0.1:8000/some/end/point'
kwargs['url'] = kwargs['url'].encode('latin-1')
kwargs['method'] = 'POST'
kwargs['data'] = data
client = HTTPClientFactory(**kwargs)
d = client.deferred
return d
Voici test_http_client.py
from StringIO import StringIO
import json
from twisted.internet.protocol import Protocol
from twisted.internet.defer import Deferred
from twisted.web.client import Agent, FileBodyProducer
from twisted.web.http_headers import Headers
class HTTPClientProtocol(Protocol):
def __init__(self, finished):
self.finished = finished
self.data = ''
def dataReceived(self, data):
print '----------Data Received by HTTPClientProtocol----------'
print data
self.data += data
def connectionLost(self, reason):
print '----------HTTP Client connection Lost----------'
print reason.getErrorMessage()
if self.finished is not None:
print 'finished is not None'
f, self.finished = self.finished, None
f.callback(self.data)
class HTTPClientFactory(object):
"""
Class handling communication with HTTP server.
"""
def __init__(self, **kwargs):
data = kwargs['data']
try:
body = FileBodyProducer(StringIO(json.dumps(data)))
print '----------Request body object created----------'
except Exception as e:
print '----------Request body object creation FAILURE----------'
print e
return e
url = kwargs.get('url', None)
method = kwargs.get('method', None)
from twisted.internet import reactor
agent = Agent(reactor)
if not data:
body = None
self.deferred = agent.request(method,
url,
Headers({'Content-Type': ['application/json']}),
bodyProducer=body)
self.deferred.addCallback(self.get_response)
def get_response(self, response):
print 'Response received'
finished = Deferred()
response.deliverBody(HTTPClientProtocol(finished))
return finished
Permet de modifier le code avez supprimé qui dépendait tout autre code sans rapport avec le problème.
Pouvez-vous essayer de réduire cela en un http://sscce.org? Il y a beaucoup de code manquant ici, donc je ne peux pas essayer d'exécuter votre exemple. Pour ce que ça vaut, la présence de Django sur le backend ne fait pas de différence ici: c'est juste Twisted qui fait une requête HTTP. Comme vous l'avez identifié, cela fonctionne de manière isolée, donc une interaction complexe avec le reste de votre système cause des problèmes, et sans voir le reste de votre système dans son intégralité, je ne peux pas dire de quoi il s'agit. (Essayer de déboguer votre système * entier * n'est vraiment utile à personne d'autre, donc plus vous pouvez l'affiner, mieux c'est.) – Glyph