Warm tip: This article is reproduced from serverfault.com, please click

javascript-Python socket.io ack函数

(javascript - Python socket.io ack function)

发布于 2020-11-23 07:06:17

在JS socket.io中,客户端的send函数中包含第三个参数:

client.emit("event name",{some:"data"},function myack(value){
})

myack函数将传递给服务器并以一些返回值调用:

//server side:
myack("foobar");
...

但是,我在Python socket.io中看不到此功能:https ://python-socketio.readthedocs.io/en/latest/api.html#asyncserver-class

可以ack从客户端JS socket.io将函数传递给Python socket.io服务器吗?假设要使用相同的应用程序协议。

Questioner
datdinhquoc
Viewed
0
Gijs Wobben 2020-11-26 17:05:07

是的,你可以看一下文档:https : //python-socketio.readthedocs.io/en/latest/server.html#event-callbacks

从这些文档中:

当客户端将事件发送到服务器时,它可以选择提供回调函数,以作为确认服务器已处理事件的一种方式被调用尽管这完全由客户端管理,但是服务器可以提供将要传递给回调函数的值的列表,只需从处理函数中返回它们即可:

@sio.event def my_event(sid, data):
    # handle the message
    return "OK", 123

同样,服务器可以在客户端处理事件之后请求调用回调函数。所述 socketio.Server.emit()方法的优点在于可以被设置为一个可调用一个可选的回调参数如果提供了此参数,则在客户端处理事件之后将调用callable,并且客户端返回的任何值都将作为参数传递给此函数。不建议在向多个客户端广播时使用回调函数,因为对于收到消息的每个客户端都会调用一次回调函数。

所以:

# main.py
import random
from flask import Flask, send_from_directory
from flask_socketio import SocketIO, emit

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


# Create a route for the index page (http://localhost:5000/)
@app.route("/")
def root():
    return send_from_directory(".", "index.html")

# Start listening for connecting clients
@socketio.on("connect")
def handle_connect():
    print("Client connected")

# Create a function to act as an ack function
def ack_random_number_received(data):
    print("The client received the random number!", data)

# Start listening for "some_event" events
@socketio.on("some_event")
def handle_some_event():

    # Create a random number (just for demo purposes)
    random_number = random.randint(0, 10)

    # Registering a "callback" function here will act as an ack function
    emit("random_number_picked", random_number, callback=ack_random_number_received)

    # Returning here will send data (a string in this case) to the ack function in JS
    return "Ack from Python"


if __name__ == "__main__":
    socketio.run(app, debug=True)
<!-- index.html -->
<html>
    <head>
        <title>My page</title>
    </head>
    <body>
        <p>The random number is: <span id="random-number">...</span></p>

        <script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js" integrity="sha256-yr4fRk/GU1ehYJPAs8P4JlTgu0Hdsp4ZKrx8bDEDC3I=" crossorigin="anonymous"></script>
        <script type="text/javascript" charset="utf-8">

            // Connect to the server
            var socket = io();

            socket.on('connect', function() {
                console.group('Event: connect');
                console.log('Emit "some_event"');
                socket.emit('some_event', {somedata: 123}, function(ack) {
                    console.group('Ack function triggered for "some_event"');
                    console.log('The server acknowledged our event, this is the response:', ack);
                    console.groupEnd();
                });
                console.groupEnd();
            });

            // Listen for events
            socket.on('random_number_picked', function(newNumber, callback) {

                // Add some logging
                console.group('Event: random_number_picked');
                console.log('The new random number is', newNumber);
                console.log('The ack function is', callback);

                // Update a part of the page
                document.getElementById("random-number").innerHTML = newNumber;

                // Invoke the callback function to send an ack to Python
                callback("Ack from JS");
                console.groupEnd();
            });

        </script>
    </body>
</html>

浏览器控制台日志

Python控制台日志