Python 服务器长轮询并启动每个RFID卡号调用的子进程。如果这种情况持续太久,我的服务器将崩溃。我怎样才能做得更好?
我需要从RFID阅读器获取RFID卡号。客户端发起此操作。客户端AJAX发布到“/user/rfid”路由。此路由返回“错误…”或rfid卡号。服务器打开检索此编号的子进程。如果服务器静坐一段时间,用户试图使用RFID登录,服务器将中断。我需要一个更好的方法来完成这个任务,或者至少清理子流程 有什么建议吗 烧瓶路径Python 服务器长轮询并启动每个RFID卡号调用的子进程。如果这种情况持续太久,我的服务器将崩溃。我怎样才能做得更好?,python,web,flask,subprocess,Python,Web,Flask,Subprocess,我需要从RFID阅读器获取RFID卡号。客户端发起此操作。客户端AJAX发布到“/user/rfid”路由。此路由返回“错误…”或rfid卡号。服务器打开检索此编号的子进程。如果服务器静坐一段时间,用户试图使用RFID登录,服务器将中断。我需要一个更好的方法来完成这个任务,或者至少清理子流程 有什么建议吗 烧瓶路径 @app.route("/user/rfid", methods=["POST"]) def user_rfid(): rfid = subprocess.Popen(["p
@app.route("/user/rfid", methods=["POST"])
def user_rfid():
rfid = subprocess.Popen(["python", "rfidSimple.py"], stdout=subprocess.PIPE).stdout.read()
print("rfid read: %s" % rfid)
if(rfid == "Exiting...."):
return json.dumps({"error":"rfid reader failure"})
else:
user = db.getUserByRFID(rfid.replace(" ",""))
if("id" in user.keys()):
# if credentials match, add user to session
session["id"] = user["id"]
# return redirect url
return json.dumps({"url":url_for("kiosk")})
else:
return json.dumps({"error":"rfid reader failure"})
rfidSimple.py
#!/usr/bin/env python
#Basic imports
from ctypes import *
import sys
#Phidget specific imports
from Phidgets.PhidgetException import PhidgetErrorCodes, PhidgetException
from Phidgets.Events.Events import AttachEventArgs, DetachEventArgs, ErrorEventArgs, OutputChangeEventArgs, TagEventArgs
from Phidgets.Devices.RFID import RFID, RFIDTagProtocol
# Rudimentary wait system variable
x = True
def rfidTagGained(e):
global x
source = e.device
sys.stdout.write(e.tag)
x = False
def main():
#Create an RFID object
try:
rfid = RFID()
except RuntimeError as e:
sys.stdout.write("Exiting...")
try:
rfid.setOnTagHandler(rfidTagGained)
except PhidgetException as e:
sys.stdout.write("Exiting...")
try:
rfid.openPhidget()
except PhidgetException as e:
sys.stdout.write("Exiting...")
try:
rfid.waitForAttach(10000)
except PhidgetException as e:
# print("Phidget Exception %i: %s" % (e.code, e.details))
try:
rfid.closePhidget()
except PhidgetException as e:
sys.stdout.write("Exiting...")
rfid.setAntennaOn(True)
while x:
# wait wait wait!
pass
exit(1)
if __name__ == '__main__':
main()
您可以启动一个单独的线程来读取进程stdout。在线程上执行连接(超时),如果线程没有终止,您知道调用花费的时间太长,您可以终止它。下面是一个示例,其中所有内容都包装到一个类中。我没有测试它,它可能有错误,但你可能会发现这个想法很有用
import threading
import subprocess
import time
class RfidSimple(threading.Thread):
def __init__(self, timeout=10):
super(theading.Thread, self).__init__()
self.end = time.time() + timeout
self.proc = subprocess.Popen(["python", "rfidSimple.py"],
stdout=subprocess.PIPE)
self.start()
def run(self):
self._result = self.proc.stdout.read()
@property
def result(self):
timeout = self.end - time.time()
if timeout > 0:
self.join(timeout)
if not self.isAlive():
self.proc.wait()
return self._result
self.proc.terminate()
self.join(5)
if not self.isAlive():
self.proc.wait()
return "Exiting..."
raise Exception("could not kill subprocess")
def user_rfid():
rfid = RfidSimple().result
print("rfid read: %s" % rfid)
if(rfid == "Exiting...."):
return json.dumps({"error":"rfid reader failure"})
else:
user = db.getUserByRFID(rfid.replace(" ",""))
if("id" in user.keys()):
# if credentials match, add user to session
session["id"] = user["id"]
# return redirect url
return json.dumps({"url":url_for("kiosk")})
else:
return json.dumps({"error":"rfid reader failure"})
我不明白。。。如果rfidSimple.py超时的时间太长,您想要一种超时方法吗?我将尝试此方法并挤压存在的错误。我要到下班后才能回到这个项目,所以我会在晚上开始。希望这是更好的解决方案!现在开始测试(让AJAX“对话”保持15分钟左右)。不过我得承认。一种可能的情况是,如果longpoll收件人不再存在(用户使用凭据而不是RFID登录)。可能只有一个线程。另外,如果我登录超过4次,我的服务器会锁定。。。啊,啊,啊