我正在尝试编写一个python网络套接字客户端,它可以接收用户生成的脚本&执行它们。
到目前为止,我的代码是这样的:
import config
import websocket
import time, ssl, json, importlib, sys
#when putting "import script" here def main is found, but not reloaded later on
script_loaded = False
def import_script(ws): #import/reload script module
global script_loaded
global script
try:
if script_loaded:
importlib.reload(script)
else:
import script
script_loaded = True
except Exception as e:
iot.report_error(ws, 'Loading Script', str(sys.exc_info()[0]), str(e))
print('Error: ' + str(sys.exc_info()[0]) + ': ' + str(e))
class iot:
def report_error(ws, place, etype, error):
msg = json.dumps({"context": 3, "place": place, "type": etype, "error": error}, sort_keys=True)
ws.send(msg)
def write(ws, socket, data):
msg = json.dumps({"context": 2, "socket": socket, "data": data}, sort_keys=True)
ws.send(msg)
def display(data):
print(data)
def start(ws): #start script module (def main)
try:
script.main(ws)
except Exception as e:
iot.report_error(ws, 'Executing Script (main())', str(sys.exc_info()[0]), str(e))
print('Error: ' + str(sys.exc_info()[0]) + ': ' + str(e))
connectionEstablished = False
def on_message(ws, message):
global connectionEstablished
global script_loaded
global script
try:
decoded_data = json.loads(message)
if decoded_data['context'] == 0: #Log on
connectionEstablished = True
elif decoded_data['context'] == 1: #Receive Script
if connectionEstablished:
file = open('script.py','w')
file.write("from iot_daemon import iotnn")
file.write(decoded_data['script']) #write received script to file (works)
import_script(ws) #import/reload script
if script_loaded:
iot.start(ws) #start script module (def main)
except Exception as e:
print('Failed to process string: ' + str(e))
def on_error(ws, error):
print('WebSocket Error: ' + error)
def on_close(ws):
print("Closed.")
def on_open(ws):
print("Connected.")
msg = json.dumps({"context": 0, "type": 0, "key": config.key}, sort_keys=True)
ws.send(msg)
if __name__ == "__main__":
while True:
if config.debugMode:
websocket.enableTrace(True)
ws = websocket.WebSocketApp(config.serverURL,
on_message = on_message,
on_error = on_error,
on_close = on_close)
ws.on_open = on_open
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
time.sleep(5)
print("Reconnecting...")
虽然接收脚本似乎有效(使用文本编辑器查看时会更新script.py),但不知何故,重新加载和执行新版本却无效(当客户端重新启动时,它总是运行现有的脚本版本,或者如果忽略了脚本顶部的import语句,它根本不运行脚本)。
任何帮助都将不胜感激。提前谢谢。
问题其实很简单:Python无法重新加载目前作为FileObject打开的模块。所以简单地添加一个"file.close()"就解决了这个问题。