Не удается скопировать объект в асинхронную функцию Python - PullRequest
0 голосов
/ 20 сентября 2019

Я делаю сервер Python WebSocket и клиент HTML с системой синхронизации сообщений.Кажется, функция UpdateData неправильно копирует объект.

Код моего сервера Python WebSocket выглядит следующим образом

import asyncio
import json
import logging
import websockets
import copy

logging.basicConfig()

m_sysObj =\
{
    "Valve":[ 
        {
            "ActualTemp": 190,
        }
    ],
    "Test": 0
}

USERS = set()

def state_event():
    return json.dumps({"type": "state", **m_sysObj})

def users_event():
    return json.dumps({"type": "users", "count": len(USERS)})

def copyData(data):
    m_sysObj = [x[:] for x in data]

async def notify_state():
    if USERS:  # asyncio.wait doesn't accept an empty list
        message = state_event()
        await asyncio.wait([user.send(message) for user in USERS])


async def notify_users():
    if USERS:  # asyncio.wait doesn't accept an empty list
        message = users_event()
        await asyncio.wait([user.send(message) for user in USERS])


async def register(websocket):
    USERS.add(websocket)
    await notify_users()

async def unregister(websocket):
    USERS.remove(websocket)
    await notify_users()

async def updateData(websocket, path):
    # register(websocket) sends user_event() to websocket
    await register(websocket)
    try:
        await websocket.send(state_event())
        async for message in websocket:
            data = json.loads(message)
            #m_sysObj = data                                    # not working
            #m_sysObj = copy.deepcopy(data)                     # not working
            #m_sysObj = [inner_list[:] for inner_list in data]  # not working
            m_sysObj["Valve"] = data["Valve"]                   # works, but I need to copy "test" as well
            await notify_state()
    finally:
        await unregister(websocket)

start_server = websockets.serve(updateData, "localhost", 6789)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

Мой код клиента HTML WebSocket поврежден

<html>
    <head>
        <title>WebSocket demo</title>
    </head>
    <body>
        <div class="buttons">
            <div class="update button">update Button</div>
            <div class="container">
                <form></form>
                  temp: <input id="temp" class="value" type="text"><br>
                </form>
            </div>
        </div>
        <div class="state">
            <span class="users">?</span> online
        </div>
        <script>
            var m_sysObj;
            var update = document.querySelector('.update'),
                users = document.querySelector('.users'),
                websocket = new WebSocket("ws://127.0.0.1:6789/");
            update.onclick = function (event) {
                m_sysObj.Valve[0].ActualTemp = +document.getElementById('temp').value;
                websocket.send(JSON.stringify(m_sysObj));
            }

            websocket.onmessage = function (event) {
                data = JSON.parse(event.data);
                switch (data.type) {
                    case 'state':
                        m_sysObj = data;
                        document.getElementById('temp').value = data.Valve[0].ActualTemp;
                        break;
                    case 'users':
                        users.textContent = (
                            data.count.toString() + " user" +
                            (data.count == 1 ? "" : "s"));
                        break;
                    default:
                        console.error(
                            "unsupported event", data);
                }
            };
        </script>
    </body>
</html>

Deepcopy не работает, значение клиента сбрасывается.Единственный способ скопировать объект - это скопировать отдельные теги.

1 Ответ

0 голосов
/ 20 сентября 2019

Я обнаружил, что проблема в функции python с глобальной переменной.Я должен установить глобальную переменную с глобальным ключевым словом

   async for message in websocket:
            data = json.loads(message)
            global m_sysObj
            m_sysObj = data
            await notify_state()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...