无法使用 twisted.web.AGENT 向 Django 服务器发出 http 请求
Unable to make http request to django server using twisted.web.AGENT
我已经编写了一个基本的 tcp 服务器工厂、服务器客户端和一个使用 twisted 的服务。 tcp 服务器充当 django 服务器和另一个程序(我们称之为 client 程序)之间的 middleware。
我想达到的目标 -
1.客户端请求中间件tcp服务器;
2.it发送一个字符串作为请求体;
3.the 中间件 tcp 服务器反序列化请求中的信息。
4.middleware进一步将序列化信息传给django服务器。
5.The django 服务器然后响应 middleware 服务器,后者在序列化响应后进一步响应 client。
我可以到达第 3 步,但无法向 Django 服务器发出任何 http 请求。
下面是我的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)
下面是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
以下是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
EDITS 删除了依赖于与问题无关的其他代码的代码。
发现错误。
下面是更正后的代码。
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 # instead of self.data += data
self.forward(self.data) # this is the right place to call this method which in turn fires the callback through which the request is made to the server.
def connectionLost(self, reason): pass
# this will not be called until the connection from client is ended.
# self.forward(self.data)
def forward(self, data):
if self.deferred is not None:
d, self.deferred = self.deferred, None
d.callback(data)
我已经编写了一个基本的 tcp 服务器工厂、服务器客户端和一个使用 twisted 的服务。 tcp 服务器充当 django 服务器和另一个程序(我们称之为 client 程序)之间的 middleware。
我想达到的目标 -
1.客户端请求中间件tcp服务器;
2.it发送一个字符串作为请求体;
3.the 中间件 tcp 服务器反序列化请求中的信息。
4.middleware进一步将序列化信息传给django服务器。
5.The django 服务器然后响应 middleware 服务器,后者在序列化响应后进一步响应 client。
我可以到达第 3 步,但无法向 Django 服务器发出任何 http 请求。
下面是我的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)
下面是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
以下是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
EDITS 删除了依赖于与问题无关的其他代码的代码。
发现错误。 下面是更正后的代码。
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 # instead of self.data += data
self.forward(self.data) # this is the right place to call this method which in turn fires the callback through which the request is made to the server.
def connectionLost(self, reason): pass
# this will not be called until the connection from client is ended.
# self.forward(self.data)
def forward(self, data):
if self.deferred is not None:
d, self.deferred = self.deferred, None
d.callback(data)