简体   繁体   中英

Python websockets, how to send message from function

I'm writing an update to my code to send a WebSocket message to a connected web browser that it needs to update its data (charting web app). This message needs to be sent when the code has inserted new data into the MySQL database. I will write some Javascript in the browser to go and get the update on receiving the message.

My test code:

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)
'''

I can send a message using the message variable.

I need the readValues and insert data functions to run continuously every 20sec regardless of what's happening with the WebSocket.

But I can't work out how to send a message to the browser from the function that updates the database. And I can't work out the best method to run the WebSocket process and the updating of the database at the same time.

I've written comments in the code to try and help you understand what I'm trying to do.

Hope you can understand, thanks, Guys.

Update: Thanks Nathan: I changed the code and do 2 files like the below: Server:

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()

process file:

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())

I then ran both of these (eaxctly as shown) and opened a web browser with this:

<!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>

Everything seems fine until I open the browser as above. Then nothing comes to the browser and apart from the 'connect' result.

WebSocket connection is closed: code = 1006 (connection closed abnormally [internal]), no reason

appears on both scripts.

You need a socket connexion between the "database handler" and the socket server :

create a second script with the main loop:

 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())

then on the other script you could have :

    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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM