#python #http #persistent
#питон #http #настойчивый
Вопрос:
Я пытаюсь создать простой HTTP-сервер, который будет получать сообщения POST и предоставлять простой ответ. Я использую стандартный HTTPServer с python. Клиент подключается с помощью session (), который должен использовать постоянное соединение, но после каждого сообщения я вижу сообщение ниже в отладке, что соединение прерывается.
ИНФОРМАЦИЯ: urllib3.connectionpool: сброс разорванного соединения:
ОТЛАДКА: urllib3.connectionpool:»GET / HTTP/ 1.1″ 200 Нет
Клиент работает правильно, когда я пытаюсь использовать его с Apache, поэтому я считаю, что проблема в моей простой конфигурации сервера. Как я могу настроить простой http-сервер для работы с постоянными подключениями?
Простой серверный код Python:
from http.server import HTTPServer, BaseHTTPRequestHandler
from io import BytesIO
import time
import datetime
import logging
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def _set_response(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.send_header("Connection", "keep-alive")
self.send_header("keep-alive", "timeout=5, max=30")
self.end_headers()
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello, world!')
def do_POST(self):
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
curr_time = datetime.datetime.now()
data = ('{"msgid":"0x0002", "timestamp": "' str(curr_time) '", "message":"Test http response from Raspberry Pi HTTP server"}').encode()
self.send_response(200)
self.end_headers()
response = BytesIO()
#response.write(b'This is POST request. ')
#response.write(b'Received: ')
response.write(data)
self.wfile.write(response.getvalue())
print("Simple HTTP Server running...")
logging.basicConfig(level=logging.DEBUG)
httpd = HTTPServer(('', 8000), SimpleHTTPRequestHandler)
httpd.serve_forever()
Клиентский код Python:
#!/usr/bin/env python
# Using same TCP connection for all HTTP requests
import os
import json
import time
import datetime
import logging
import requests
from requests.auth import HTTPBasicAuth
logging.basicConfig(level=logging.DEBUG)
start_time = time.time()
def get_data(limit):
session = requests.Session()
url = "http://localhost:8000"
for i in range(10):
curr_time = datetime.datetime.now()
data = '{"msgid":"0x0001", "timestamp": "' str(curr_time) '", "message":"Test http message from Raspberry Pi"}'
print("Sending Data: " data)
response = session.post(url.format(limit), data)
#response_dict = json.loads(response.text)
print("Received Data: " response.text)
if __name__ == "__main__":
limit = 1
get_data(limit)
print("--- %s seconds ---" % (time.time() - start_time))
Ответ №1:
На самом деле вы не устанавливаете Connection
заголовок в своем обработчике POST. Для того, чтобы постоянные соединения работали, вам также необходимо установить Content-Length
заголовок в ответе, чтобы клиент знал, сколько байтов тела HTTP нужно прочитать перед повторным использованием соединения.
Попробуйте этот обработчик POST, адаптированный из вашего кода:
def do_POST(self):
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
# Process the request here and generate the entire response
response_data = b'{"stuff": 1234}'
# Send the response
self.send_response(200)
self.send_header("Connection", "keep-alive")
self.send_header("Content-Length", str(len(response_data)))
self.end_headers()
# Write _exactly_ the number of bytes specified by the
# 'Content-Length' header
self.wfile.write(response_data)