我有一个 Flask 服务器,带有用于 Meraki Alerts 的 Webhook 端点(“host_url/endpoint”)。
服务器还有一个页面应该显示所有收到的警报(“host_url/view”)。
我希望发生的是,当 Meraki 向我的端点发送 Webhook 时,“host_url/view”上的所有客户端都会更新以显示最新警报。
我尝试过每隔几秒简单地轮询一次,但即使它有效,我也想避免使用这种解决方案。
我也尝试过使用 websockets,但标准
flask_socketio
实现要求从服务器发送的消息位于用 @socketio.on("...")
装饰器装饰的函数内。
例如
@socketio.on("connect")
def send_message():
emit("msg")
但是由于触发此类消息的事件本身不是 websocket 事件,我需要能够在 socketio 函数之外发送消息。
例如
def send_message():
emit("msg")
我的目标是拥有一个函数
send_to_all_clients(data)
,我可以在代码中的任何地方使用它,并且发送一个可由 Javascript 事件处理程序接收的事件。
要将事件发送给所有客户端,我建议查看 Flask-SocketIO 文档的 “广播” 部分。这里描述了如何使用
socketio.emit(eventName, data)
发送事件(例如从正常路由),以便所有连接的客户端都可以接收该事件。
在以下示例中,按下按钮时,示例事件将发送到 webhook,然后传递给所有客户端。使用 Postman 肯定会更明智。
from flask import (
Flask,
render_template,
request
)
from flask_socketio import SocketIO
app = Flask(__name__)
sock = SocketIO(app)
@app.route('/')
def index():
return render_template('index.html')
def send_to_all_clients(data):
sock.emit('details', data)
@app.post('/webhook')
def webhook():
data = request.get_json(force=True)
send_to_all_clients(data)
return '', 200
if __name__ == '__main__':
sock.run(app)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Index</title>
</head>
<body>
<button id="snd">Call Webhook</button>
<pre><output id="out"></output></pre>
<script
src="https://cdn.socket.io/4.7.2/socket.io.min.js"
integrity="sha384-mZLF4UVrpi/QTWPA7BjNPEnkIfRFn4ZEO3Qt/HFklTJBj/gBOV8G3HcKn4NfQblz"
crossorigin="anonymous"></script>
<script>
(function() {
const sock = io();
sock.on('details', (...args) => {
const elem = document.getElementById('out');
elem.innerText += JSON.stringify(args) + '\n';
});
document.getElementById('snd').addEventListener('click', () => {
const data = {
"version": "0.1",
"sharedSecret": "secret",
"sentAt": "2021-10-07T08:38:40.522804Z",
"organizationId": "2930418",
"organizationName": "My organization",
"organizationUrl": "https://dashboard.meraki.com/o/VjjsAd/manage/organization/overview",
"networkId": "N_24329156",
"networkName": "Main Office",
"networkUrl": "https://n1.meraki.com//n//manage/nodes/list",
"networkTags": [],
"deviceSerial": "Q234-ABCD-5678",
"deviceMac": "00:11:22:33:44:55",
"deviceName": "My access point",
"deviceUrl": "https://n1.meraki.com//n//manage/nodes/new_list/000000000000",
"deviceTags": [
"tag1",
"tag2"
],
"deviceModel": "MR",
"alertId": "0000000000000000",
"alertType": "APs came up",
"alertTypeId": "started_reporting",
"alertLevel": "informational",
"occurredAt": "2018-02-11T00:00:00.123450Z",
"alertData": {}
};
fetch('/webhook', {
method: 'post',
body: JSON.stringify(data)
});
})
})();
</script>
</body>
</html>