使用 Flask ping 远程 PC,导致服务器阻塞
Pinging a remote PC with Flask, causing server to block
我有一个内部网站,它需要有文件共享链接,这些链接是指向 table 行代表的电脑上共享位置的直接链接。
访问链接时,我想首先以最快的方式测试远程电脑是否可用。我认为这将是一个 ping,但由于某种原因,超时不适用于 -w
(是 windows)
这不允许花费时间,出于某种原因,它会导致 Web 服务器阻塞 ping,即使我正在使用 Tornado 异步提供 Flask 路由。
最好让服务器不断更新前端,有active/deactive个链接,允许用户只能访问pc在线的链接,限制否则他们。甚至可能维护数据库中的值。
欢迎任何建议,我以前从未真正使用过文件共享。
后端是 Python 3.4,Flask 和 Tornado。
Ajax调用
function is_drive_online2(sender){
hostname = sender.parentNode.parentNode.id;
$.get('Media/test',{
drive: hostname
},
function(returnedData){
console.log(returnedData[hostname]);
if(returnedData[hostname] == 0){
open("file://"+hostname+"/MMUsers");
}else{
alert("Server Offline");
}
}
);
}
响应(Flask 路线)
@app.route('/Media/test', methods=['GET', 'POST'])
def ping_response():
before = datetime.datetime.now()
my_dict = dict()
drive = request.args.get('drive')
print(drive)
response = os.system("ping -n 1 -w 1 " + drive)
my_dict[drive] = response
after = datetime.datetime.now()
print(after-before)
return json.dumps(my_dict), 200, {'Content-Type': 'application/json'}
ping 调用需要 18 秒才能解决,即使使用 -w 1(或 1000)也是如此
我只需要支持 Internet Explorer 11。这是否合理?像这样的东西是否有硬件限制服务器是否应该有一个长线程,其唯一任务是不断更新 active/deactivate 链接?我不确定最好的方法。
感谢阅读。
编辑 1:
正在尝试将 ping_response 应用为本机 Tornado 异步响应。结果一样
class PingHandler(RequestHandler):
@asynchronous
def get(self):
dr = self.get_argument('drive')
print(dr)
b = datetime.datetime.now()
myreturn = {self.get_argument('drive'):
os.system("ping -n 1 -w 1 " + self.get_argument('drive'))}
a = datetime.datetime.now()
print(a-b)
self.write(myreturn)
wsgi = WSGIContainer(app)
application = Application([(r"/Media/test", PingHandler),
(r".*", FallbackHandler, dict(fallback=wsgi))])
application.listen(8080)
IOLoop.instance().start()
编辑 2:尝试使用芹菜。还在阻塞。
def make_celery(app):
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
TaskBase = celery.Task
class ContextTask(TaskBase):
abstract = True
def __call__(self, *args, **kwargs):
with app.app_context():
return TaskBase.__call__(self, *args, **kwargs)
celery.Task = ContextTask
return celery
celery = make_celery(app)
@celery.task
def ping(drive):
"""
Background Task to test is computer is online
:param drive: The drive name to test
:return: Non Zero status code for Offline boxes.
"""
response = os.system("ping -n 1 -w 1 " + drive)
return json.dumps({drive: response}), 200, {'Content-Type': 'application/json'}
@app.route('/Media/test', methods=['GET', 'POST'])
def ping_response():
before = datetime.datetime.now()
my_dict = dict()
drive = request.args.get('drive')
print(drive)
this_drive = temp_session.query(Drive).filter(Drive.name == drive).first()
address = this_drive.computer.ip_address if this_drive.computer.ip_address else this_drive.name
response = ping.apply_async(args=[address])
return response
Tornado 没有异步地为您的 Flask 应用提供服务(这是不可能的:asynchronousness is a property of the interface and ping_response
is a synchronous function). Tornado's WSGIContainer
is a poor fit for what you're trying to do (see the warning 在它的文档中)
您应该将 Flask 与 gunicorn 或 uwsgi 等多线程服务器一起使用,或者使用原生 Tornado 异步 RequestHandlers
。
我有一个内部网站,它需要有文件共享链接,这些链接是指向 table 行代表的电脑上共享位置的直接链接。
访问链接时,我想首先以最快的方式测试远程电脑是否可用。我认为这将是一个 ping,但由于某种原因,超时不适用于 -w
(是 windows)
这不允许花费时间,出于某种原因,它会导致 Web 服务器阻塞 ping,即使我正在使用 Tornado 异步提供 Flask 路由。
最好让服务器不断更新前端,有active/deactive个链接,允许用户只能访问pc在线的链接,限制否则他们。甚至可能维护数据库中的值。
欢迎任何建议,我以前从未真正使用过文件共享。
后端是 Python 3.4,Flask 和 Tornado。
Ajax调用
function is_drive_online2(sender){
hostname = sender.parentNode.parentNode.id;
$.get('Media/test',{
drive: hostname
},
function(returnedData){
console.log(returnedData[hostname]);
if(returnedData[hostname] == 0){
open("file://"+hostname+"/MMUsers");
}else{
alert("Server Offline");
}
}
);
}
响应(Flask 路线)
@app.route('/Media/test', methods=['GET', 'POST'])
def ping_response():
before = datetime.datetime.now()
my_dict = dict()
drive = request.args.get('drive')
print(drive)
response = os.system("ping -n 1 -w 1 " + drive)
my_dict[drive] = response
after = datetime.datetime.now()
print(after-before)
return json.dumps(my_dict), 200, {'Content-Type': 'application/json'}
ping 调用需要 18 秒才能解决,即使使用 -w 1(或 1000)也是如此
我只需要支持 Internet Explorer 11。这是否合理?像这样的东西是否有硬件限制服务器是否应该有一个长线程,其唯一任务是不断更新 active/deactivate 链接?我不确定最好的方法。
感谢阅读。
编辑 1:
正在尝试将 ping_response 应用为本机 Tornado 异步响应。结果一样
class PingHandler(RequestHandler):
@asynchronous
def get(self):
dr = self.get_argument('drive')
print(dr)
b = datetime.datetime.now()
myreturn = {self.get_argument('drive'):
os.system("ping -n 1 -w 1 " + self.get_argument('drive'))}
a = datetime.datetime.now()
print(a-b)
self.write(myreturn)
wsgi = WSGIContainer(app)
application = Application([(r"/Media/test", PingHandler),
(r".*", FallbackHandler, dict(fallback=wsgi))])
application.listen(8080)
IOLoop.instance().start()
编辑 2:尝试使用芹菜。还在阻塞。
def make_celery(app):
celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
celery.conf.update(app.config)
TaskBase = celery.Task
class ContextTask(TaskBase):
abstract = True
def __call__(self, *args, **kwargs):
with app.app_context():
return TaskBase.__call__(self, *args, **kwargs)
celery.Task = ContextTask
return celery
celery = make_celery(app)
@celery.task
def ping(drive):
"""
Background Task to test is computer is online
:param drive: The drive name to test
:return: Non Zero status code for Offline boxes.
"""
response = os.system("ping -n 1 -w 1 " + drive)
return json.dumps({drive: response}), 200, {'Content-Type': 'application/json'}
@app.route('/Media/test', methods=['GET', 'POST'])
def ping_response():
before = datetime.datetime.now()
my_dict = dict()
drive = request.args.get('drive')
print(drive)
this_drive = temp_session.query(Drive).filter(Drive.name == drive).first()
address = this_drive.computer.ip_address if this_drive.computer.ip_address else this_drive.name
response = ping.apply_async(args=[address])
return response
Tornado 没有异步地为您的 Flask 应用提供服务(这是不可能的:asynchronousness is a property of the interface and ping_response
is a synchronous function). Tornado's WSGIContainer
is a poor fit for what you're trying to do (see the warning 在它的文档中)
您应该将 Flask 与 gunicorn 或 uwsgi 等多线程服务器一起使用,或者使用原生 Tornado 异步 RequestHandlers
。