我想通过网站(html,js)向用户提供操作。客户端(python)连接到服务器(python),并等待转换/替换/删除文件或目录的请求(python)。
我编写了以下代码,将操作从flask传递到管道PIPE_WEBSERVER
,该管道会将其转发到主线程,再将其转发到客户线程,该客户线程会将其发送给客户端。
我实现了libmessage.py
和libcon.py
来处理所有烦人的零散数据包和内容。
#!/usr/bin/env python3
import socket
import selectors
import threading
import multiprocessing
import time
from flask import Flask, request
import libcon
import libmessage
CON_THREAD_LIST = []
PIPE_WEBSERVER = None
myThread = threading.Thread()
def flask_server():
app = Flask(__name__)
def sever_thread_func():
sel = selectors.DefaultSelector()
host, port = '', int('65432') # should be replaced by config file
listen_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listen_sock.bind((host, port))
listen_sock.listen()
print("listening on", (host, port))
global PIPE_WEBSERVER
global CON_THREAD_LIST
PIPE_WEBSERVER, pipe_thread = multiprocessing.Pipe()
sel.register(listen_sock, selectors.EVENT_READ, data=None)
sel.register(pipe_thread, selectors.EVENT_READ, data=None)
while True:
events = sel.select(timeout=None)
for key, mask in events:
if key.fileobj == pipe_thread:
request_message = pipe_thread.recv()
#next step: deliver to correct conection-thread by iterate through CON_THREAD_LIST
found = False
for con in CON_THREAD_LIST:
if request_message['addr'] == con['addr']:
found = True
con['pipe'].send(request_message)
response_message = con['pipe'].recv()
if not found:
response_message = libmessage.Message.create_request('status', 'invalid addr')
pipe_thread.send(response_message)
elif key.fileobj == listen_sock:
con_sock, addr = listen_sock.accept()
print("accepted connection from ", addr)
pipe_parent, pipe_child = multiprocessing.Pipe()
new_thread = threading.Thread(target=libcon.create_connection_sock,
args=(con_sock, addr, pipe_child))
new_thread.start()
thread_infos = {'thread': new_thread,
'pipe' : pipe_parent,
'addr' : addr[0]}
CON_THREAD_LIST.append(thread_infos)
sel.register(pipe_parent, selectors.EVENT_READ, data=thread_infos)
else:
client_thread = key.data
if client_thread in CON_THREAD_LIST:
sel.unregister(key.fileobj)
CON_THREAD_LIST.remove(client_thread)
print('CON_THREAD_LIST_t-ID: ' + hex(id(CON_THREAD_LIST)))
print('Threads in list: ' + str(len(CON_THREAD_LIST)))
threads_to_remove = []
for client_info in CON_THREAD_LIST:
res_running = client_info['thread'].is_alive()
print('is thread to ' + client_info['addr'] + ' running? : ' + str(res_running))
if not res_running:
threads_to_remove.append()
for thread_to_remove in threads_to_remove:
CON_THREAD_LIST.remove(thread_to_remove)
print('active threads: ' + str(threading.active_count()))
myThread = threading.Timer(1, sever_thread_func, args=())
myThread.start()
time.sleep(0.1) #not quite sure why needed
print('try to start my stuff -------------')
return app
app = flask_server()
print('started server')
@app.route('/testHello/test')
def get_my_files():
name = request.args.get('name')
#addr = request.args.get('addr')
addr = '192.168.1.17'
message = libmessage.Message.create_request('list_files', name, addr)
PIPE_WEBSERVER.send(message)
sel_request = selectors.DefaultSelector()
sel_request.register(PIPE_WEBSERVER, selectors.EVENT_READ, data=None)
events = sel_request.select(timeout=None)
for key, mask in events:
if key.fileobj == PIPE_WEBSERVER:
result = PIPE_WEBSERVER.recv()
print(result)
return result['result']
@app.route('/testHello/connected')
def say_connected_clients():
global CON_THREAD_LIST
print('CON_THREAD_LIST_f-ID: ' + hex(id(CON_THREAD_LIST)))
result = ''
result += str(len(CON_THREAD_LIST))
return result
我的问题是CON_THREAD_LIST
中的say_connected_clients
具有相同的ID,但是我没有相同的元素。但是,当我打电话给http://localhost/testHello/test
时,我会从客户ergo PIPE_WEBSERVER
那里获得列表。
我知道线程的常见问题(互斥体,锁,线程安全等),但是在这一年龄段,我不确定真正的问题是什么。我只想使用管道通过一个应用程序以短方式处理它。
有人可以为我提供一个真正好用的烧瓶和Python解决方案吗?