Skip to main content
 首页 » 编程设计

Python websockets,如何从函数发送消息

2024年09月03日43yxwkf

我正在编写代码更新,以将 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) 
''' 

我可以使用消息变量发送消息。

无论 WebSocket 发生什么情况,我都需要每 20 秒连续运行一次读取值和插入数据函数。

但我不知道如何从更新数据库的函数向浏览器发送消息。而且我无法找出同时运行 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> 

在我按上述方式打开浏览器之前,一切似乎都很好。 然后除了“连接”结果之外,浏览器什么也没有。

WebSocket 连接关闭:code = 1006(连接异常关闭[内部]),无原因

出现在两个脚本中。

请您参考如下方法:

您需要在“数据库处理程序”和套接字服务器之间建立套接字连接:

用主循环创建第二个脚本:

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