Постоянные соединения простого сервера Python HTTP - PullRequest
0 голосов
/ 19 апреля 2019

Я пытаюсь создать простой HTTP-сервер, который будет получать сообщения POST и предоставлять простой ответ.Я использую стандартный HTTPServer с Python.Клиент подключается с помощью сеанса (), который должен использовать постоянное соединение, но после каждого POST я вижу сообщение отладки о том, что соединение прерывается.*

DEBUG: 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 Ответ

1 голос
/ 19 апреля 2019

Вы на самом деле не устанавливаете заголовок 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)
...