0

我正在尝试编写一个 python Web 套接字客户端,它可以接收用户生成的脚本并执行它们。

到目前为止,我的代码如下所示:

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 iot\n\n")
                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 语句被省略,它根本不会运行脚本)。

任何帮助将非常感激。提前致谢。

4

1 回答 1

0

问题实际上是一个非常简单的问题:Python 无法重新加载目前作为 FileObject 打开的模块。因此,只需添加“file.close()”即可解决。

于 2015-12-13T15:38:17.177 回答