python - Python websockets,如何从函数发送消息
问题描述
我正在编写我的代码更新,以将 WebSocket 消息发送到连接的 Web 浏览器,它需要更新其数据(图表 Web 应用程序)。当代码将新数据插入 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 发生了什么,我都需要 readValues 和 insert data 函数每 20 秒连续运行一次。
但我不知道如何从更新数据库的功能向浏览器发送消息。而且我无法找出同时运行 WebSocket 进程和更新数据库的最佳方法。
我在代码中写了注释,试图帮助你理解我想要做什么。
希望各位大侠能理解,谢谢。
更新:感谢 Nathan:我更改了代码并执行了 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()
推荐阅读
- eclipse - Eclipse Maven 缺少工件 com.sun.jersey:jersey-servlet:jar:1.20-SNAPSHOT
- symfony - EventSubscriber 不会被事件触发
- jquery - jQuery:循环更改图像问题
- intellij-idea - 使用 IntelliJ IDEA 创建 Kotlin jar 时出现“无主清单属性”
- reactjs - Axios 数据在发送到 Flask POST 路由时以 ImmutableMultiDict([]) 的形式出现,但与 Postman 一起使用
- python - 是否可以将 CNN 中层的输出发送到并行工作的多个层和组卷积节点?
- c++11 - 创建相互依赖于其“容器”类的对象的可接受做法?
- javascript - 如何在表单提交时防止表单在刷新时重新提交
- reactjs - Reactjs 组件状态下的单元测试 Jest
- .net - kendo 下拉列表值未正确传递到服务器端代码