在Flask中发布请求后如何使用WebSocket向客户端发送警报

时间:2018-11-11 04:40:00

标签: python rest post flask websocket

发出发布请求后,如何向客户发送消息?我将发布请求中的数据存储到数据库中,并且想通知客户端数据库已更改。有没有办法将restapi与websocket相结合?我发现的示例正在使用websockets接收数据并发送到客户端,而我正在使用post方法接收并想使用websocket进行警报。任何帮助,将不胜感激。

server.py

import sqlite3
from flask import Flask, render_template
from flask_socketio import SocketIO

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

@app.route('/', methods=['GET'])
def index():
    render_template('index.html')

# listen for data
@app.route('/listen/<data>',methods=['POST'])
def listen(data):
    # insert to db
    conn = sqlite3.connect('storage.db')
    c = conn.cursor()
    c.execute('''CREATE TABLE info(num text)''')
    c.execute('''INSERT INTO info(num) VALUES(?)''',(data))
    conn.commit()
    conn.close()

    #send alert to client

@socketio.on('message')
def handle_message(message):
    send(message)

if __name__ == '__main__':
    socketio.run(app)

index.html

<head>
<script type="text/javascript"src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">
        var socket = io.connect('http://' + document.domain + ':' + location.port);
        socket.on('message', function(data) {
             console.log(data);
        });
  </script>
</head>

2 个答案:

答案 0 :(得分:0)

您只是以错误的方式得到它。您的flask-socketio中的sendemit应该是POST请求后的最后一条语句,如下所示:

import sqlite3
from flask import Flask, render_template
from flask_socketio import SocketIO, emit

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

@app.route('/', methods=['GET'])
def index():
    render_template('index.html')

# listen for data
@app.route('/listen/<data>',methods=['POST'])
def listen(data):
    # insert to db
    conn = sqlite3.connect('storage.db')
    c = conn.cursor()
    c.execute('''CREATE TABLE info(num text)''')
    c.execute('''INSERT INTO info(num) VALUES(?)''',(data))
    conn.commit()
    conn.close()

    emit('message', 'Change has been made', broadcast=True) # To send all who listen

# This part is, if client sends to server something through 'message' socket. You don't need that,
# @socketio.on('message')
# def handle_message(message):
    # send(message)

if __name__ == '__main__':
    socketio.run(app)

由于客户端侦听来自“消息”套接字的消息,因此需要像下面这样在index.html中进行处理:

<head>
<script type="text/javascript"src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">
        var socket = io.connect('http://' + document.domain + ':' + location.port);
        socket.on('message', function(data) {
             console.log(data);
        });
  </script>
</head>

客户端服务器端。 他们俩都听socket.on()进行一些更改。他们使用send()emit()发送消息或发出消息。

客户端可以通过'ImHere'套接字发出->服务器将使用socket.on('ImHere')处理该消息->服务器可以使用emitsend触发其他套接字,可以说'message'套接字->客户端可以通过`socket.on('message',function(data){...})来处理它。

答案 1 :(得分:0)

您已经拥有@Dinko提到的所有功能,只需在conn.close()之后的监听函数中再添加一个,即可:

socketio.emit('message', {'data': 'Records Affected'}, broadcast=True)

您的回叫功能将被触发,因为它将听到“消息”套接字。

这里要添加的另一件事是,如果您具有用于特定频道的名称空间,那么您也需要传递该名称空间

socketio.emit('message', {'data': 'Records Affected'}, broadcast=True, namespace='/test')

希望这会有所帮助..!