Python websockets, как отправить сообщение из функции - PullRequest
0 голосов
/ 12 февраля 2019

Я пишу обновление для своего кода, чтобы отправить сообщение WebSocket подключенному веб-браузеру о необходимости обновления данных (веб-приложение для построения диаграмм).Это сообщение необходимо отправить, когда код вставит новые данные в базу данных MySQL.Я напишу в браузере Javascript и получу обновление при получении сообщения.

Мой тестовый код:

import asyncio
#import time
import websockets


def readValues():
    '''do stuff that returns the values for database'''
    pass


def inserdata(val):
    '''insert values into mysql'''
    pass


async def ph(websocket, path):
    while True:
        message = 'update' 
        # here we receive message that the data
        # has been added and need to message the
        # browser to update
        print('socket executed')
        await websocket.send(message)
        await asyncio.sleep(2)
        # shouldn't be needed as message
        # sent only when updated data
        # inserted(every 20s)


async def main():  # maybe use this to get/write to the database etc
    while True:  # instead of the loop at bottom
        print('main executed')
        await asyncio.sleep(20)

start_server = websockets.serve(ph, '0.0.0.0', 5678)

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

#below copied from current program
'''
while 1:
    try:
        a = readValues() #read valves from a function
        insertdata(a) #function to write values to mysql

        #some method to send the message to the web browser via -
        #websocket, that it needs to get the new data

        time.sleep(20) #wait and then do it again
    except Exception as e:
        print(e)
'''

Я могу отправить сообщение с помощью переменной message.

Мне нужно, чтобы функции readValues ​​и вставки данных работали непрерывно каждые 20 секунд, независимо от того, что происходит с WebSocket.

Но я не могу понять, как отправить сообщение в браузер с помощью функции, котораяобновляет базу данных.И я не могу найти лучший метод для одновременного запуска процесса WebSocket и обновления базы данных.

Я написал комментарии в коде, чтобы попытаться помочь вам понять, что япытаюсь сделать.

Надеюсь, вы понимаете, спасибо, ребята.

Обновление: Спасибо, Натан: Я изменил код и делаю 2 файла, как показано ниже: Сервер:

import asyncio
import websockets

async def ph(websocket, path):
    while True:
        need_update = await websocket.recv()
        print('socket executed')
        await websocket.send(need_update)


start_server = websockets.serve(ph, '0.0.0.0', 5678)

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

файл процесса:

import asyncio
import time
import websockets

async def main():
    async with websockets.connect('ws://127.0.0.1:5678') as websocket:
        while 1:
            try:
                #a = readValues() #read values from a function
                #insertdata(a) #function to write values to mysql
                await websocket.send("updated")
                print('data updated')
                time.sleep(20) #wait and then do it again
            except Exception as e:
                print(e)

asyncio.get_event_loop().run_until_complete(main())

Затем я запустил оба из них (как показано на рисунке) и открыл веб-браузер с этим:

<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
        <h3>
        Test
        </h3>
        <p>
            <div id="log"></div>
        </p>
        <script>
            // helper function: log message to screen
            function log(msg) {
                document.getElementById('log').innerText += msg + '\n';
            }

            // setup websocket with callbacks
            var ws = new WebSocket('ws://192.168.0.224:5678/');
            ws.onopen = function() {
                log('CONNECT');
            };
            ws.onclose = function() {
                log('DISCONNECT');
            };
            ws.onmessage = function(event) {
                log('MESSAGE: ' + event.data);
            };
        </script>
    </body>
</html>

Все выглядит нормально, пока я не откроюбраузер, как указано выше.Тогда в браузер ничего не приходит и, кроме результата «connect».

Соединение WebSocket закрыто: code = 1006 (соединение закрыто ненормально [внутреннее]), без причины

появляется в обоих скриптах.

1 Ответ

0 голосов
/ 12 февраля 2019

Вам необходимо соединение с сокетом между «обработчиком базы данных» и сервером сокетов:

создайте второй скрипт с основным циклом:

 async def main():
    async with websockets.connect(websocket_address) as websocket:
        while 1:
            try:
                a = readValues() #read values from a function
                insertdata(a) #function to write values to mysql
                await websocket.send("some token to recognize that it's the db socket")
                time.sleep(20) #wait and then do it again
             except Exception as e:
                print(e)

asyncio.get_event_loop().run_until_complete(main())

, затем на другом скрипте вы можетеиметь:

    USERS = set()
    def register(websocket):
        USERS.add(websocket)

    async def ph(websocket, path):
        while True:
            register(websocket) #not sure if you need to place it here
            need_update = await websocket.recv()
            #check unique token to verify that it's the database
            message = 'update'#here we receive message that the data
                              #has been added and need to message the
                              #browser to update
            print('socket executed')
            if USERS:       # asyncio.wait doesn't accept an empty list
                await asyncio.wait([user.send(message) for user in USERS])


    start_server = websockets.serve(ph, '0.0.0.0', 5678)

    asyncio.get_event_loop().run_until_complete(start_server)
    asyncio.get_event_loop().run_forever()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...