我有一个Raspberry Pi,运行最新的Raspbian,执行一个简单的Python Web服务器。下面是这部分的代码。
# This is the main class for the web server
class MyHandler(BaseHTTPRequestHandler):
# These are the headers that are sent as a response to every request
def _set_headers(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
# This is the new POST method to get around background refresh problems
def do_POST(self):
# Get the content of the POST request
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
# Split the text on the = of the key value pair, and keep the text of the operation.
operationRequested = post_data.split("=")[1];
logging.info(self.client_address[0] + " has requested operation " + operationRequested)
# Handle each type of request. It's limited by the HTML file.
if operationRequested == "openLeftDoor":
leftDoor.openDoor()
if operationRequested == "closeLeftDoor":
leftDoor.closeDoor()
if operationRequested == "openRightDoor":
rightDoor.openDoor()
if operationRequested == "closeRightDoor":
rightDoor.closeDoor()
self._set_headers()
self.wfile.write(operationRequested + " completed.")
# This is how we handle a GET request. We sense the URL within this method
def do_GET(self):
logging.info(self.client_address[0] + " has requested page " + self.path)
# Handle the GET for the log file.
if self.path == '/getlogs':
try:
htmlPage = open(logFilename)
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
# Change carriage returns to HTML line breaks
logFile = htmlPage.read()
logFile = logFile.replace('\n', '<br>')
self.wfile.write(logFile)
self.wfile.write(htmlPage.read())
htmlPage.close()
return
except IOError:
logging.info("An IO Error happened during get logs!")
# Handle the root request for the welcome page. This can't be an else as that disallows favicon requests.
if self.path == "/":
try:
htmlPage = open("WelcomePage.html")
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
self.wfile.write(htmlPage.read())
htmlPage.close()
return
except IOError as e:
logging.info("An IO Error happened during get welcome page!")
logging.info(repr(e))
# This is the entry point to the webserver. The try catch looks after closing the socket with Ctrl C.
try:
myServer = SocketServer.TCPServer(("", 80), MyHandler)
myServer.serve_forever()
except KeyboardInterrupt:
logging.info(' received, shutting down the web server')
finally:
myServer.server_close()
logging.info("Server has been closed")
logging.info("Bye!")
只有在我的局域网内才能访问这个网站 有线和无线客户端都能访问。我在使用基于Windows 10的笔记本电脑时从来没有遇到过问题,但是在iOS上可能有50%的时间,初始页面的加载速度非常慢,可能需要30秒。代码没有抛出任何异常,我已经能够找到。
这种情况似乎在iOS上将页面添加到主屏幕与在Safari中添加书签时更为普遍。都是只用IP地址,根本没有DNS解析。
一旦iOS设备第一次加载了页面,后续对同一服务器的浏览都是即时的。
我已经验证了Pi的wifi没有设置为睡眠状态,这是一个RSSI SNR极好的区域。我已经在两部不同的iPhone上重现了它。
这是因为我在webserver中没有设置favicon.ico和它的衍生品造成的。
当在iPhone上打开页面时,特别是从主屏幕上打开,在后台设备会请求这些图标。web服务器并没有设置成处理同时请求的状态,所以在处理用户的请求和渲染页面之前,它都处于等待每次请求超时的状态。
我通过在do_GET方法中增加一个else case来解决这个问题,处理通配符URL,返回一个默认图标。