语境
我有一个运行一些 Python 代码的 Pycom WiPy 板。_urequest
该代码使用模块向 .NET Web API 发出 HTTP Post 请求。
问题
当发送 HTTP Post 请求时,[Errno 202] EAI_FAIL
会引发异常。这种情况一个接一个地发生了好几次,因为请求在循环中每 10 秒发送一次。
代码
Wifi客户端,连接到本地wifi并获得互联网访问权限
import json
import time
from network import WLAN
# Wifi client singleton
wifiClient = None
def initWifiClient():
global wifiClient
wifiClient = WifiClient()
def getWifiClient():
global wifiClient
return wifiClient
class WifiClient:
wifi = None
lastWifiConnectAttempt = None
def __init__(self):
self.wifi = WLAN(mode=WLAN.STA)
pass
def connect(self):
if not self.__readyForNewWifiConnectAttempt():
print("Not ready yet for new WIFI connect attempt.")
self.__printSecondsLeftToNextConnectAttempt()
return
print("Trying to connect WIFI.")
try:
self.lastWifiConnectAttempt = time.time()
with open('wifi.json') as json_file:
wifiJson = json.load(json_file)
self.wifi.connect(ssid=wifiJson['ssid'], auth=(WLAN.WPA2, wifiJson['password']), timeout=30000)
# Add connection timeout handler to prevent timeout exception crash.
self.wifi.callback(WLAN.SMART_CONF_TIMEOUT, handler=self.__onWifiConnectTimeout)
pass
except Exception as e:
self.lastWifiConnectAttempt = None
print (e)
pass
def __readyForNewWifiConnectAttempt(self):
if self.lastWifiConnectAttempt == None:
return True
return (time.time() - self.lastWifiConnectAttempt) > 42
def __onWifiConnectTimeout(self, args):
self.lastWifiConnectAttempt = None
pass
# For debugging
def __printSecondsLeftToNextConnectAttempt(self):
secondsLeft = 43 - (time.time() - self.lastWifiConnectAttempt)
if secondsLeft < 0:
secondsLeft = 0
print("Seconds left to be ready for next WIFI connect attempt: " + str(secondsLeft))
Web api 调用者/客户端代码,用于向 Web api 发送不同调用的帮助模块:
此 mdoule 运行后台工作循环,该循环进行 api 调用并捕获[Errno 202] EAI_FAIL
异常。
from machine import Timer
from hardware import web, unit
from events import commands as cmd
from util import weblog
import ujson
import pycom
import gc
from hardware.wifi_client import getWifiClient
# globals for this file
_background_timer = None
_background_app = None
def get_client():
client = web.Client()
client.base_url = "..."
# client.base_url = "..."
return client
def send_data():
print ("sending data")
client = get_client()
client.headers['Content-Type'] = 'application/json'
# client.headers['Accept'] = '*/*'
# client.headers['User-Agent'] = 'PostmanRuntime/7.28.4'
# client.headers['Host'] = '...'
# client.headers['Connection'] = 'keep-alive'
p = cmd.Measure()
data = {
'uuid' : unit.ID,
'value' : round(p, 1),
'measured': "1970-01-01T00:00:00.000Z"
}
response = client.post('ApiMethod', data)
print (response.text)
pass
def background_work(o):
global _background_app
global wifiClient
try:
pycom.rgbled(0)
gc.collect()
mfree = gc.mem_free()
print ("Memfree: " + str(mfree))
if (getWifiClient().wifi.isconnected()):
if (mfree < 1000000):
weblog.warning("Memory low: %d", mfree)
print("Memory low: %d", mfree)
send_data()
app = _background_app
fetch_data(app)
pycom.rgbled(0x002f00)
else:
pycom.rgbled(0x2F)
print ("Not connected to WIFI")
getWifiClient().connect()
except Exception as e:
pycom.rgbled(0x2f0000)
print("send exception")
print(e)
pass
pass
def stop_background():
global _background_timer
if _background_timer:
_background_timer.cancel()
_background_timer = None
pass
def start_background(app):
global _background_timer, _background_app
stop_background()
_background_app = app
_background_timer = Timer.Alarm(background_work, s=10, periodic=True)
pass
HTTP 客户端,对 api 进行 HTTP 调用:
import _urequest as ureq
class Client:
def __init__(self):
self.headers = {}
self.base_url = ""
pass
...
def post(self, url, payload):
print(self.base_url)
print(self.base_url + url)
return ureq.post(self.base_url + url, headers = self.headers, json = payload)
...
def base(self, url):
self.base_url = url
控制台输出
sending data
send exception
[Errno 202] EAI_FAIL
Memfree: 2527712
sending data
send exception
[Errno 202] EAI_FAIL
Memfree: 2527712
sending data
问题
为什么会[Errno 202] EAI_FAIL
抛出异常?
谢谢!