简体   繁体   English

Python socket.io ack 函数

[英]Python socket.io ack function

In JS socket.io, there's the third param in the emit function of client:在JS socket.io中,客户端的emit函数中有第三个参数:

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

The myack function is passed to server and called with some returning value: myack函数被传递到服务器并使用一些返回值调用:

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

However, I don't see this feature in Python socket.io: https://python-socketio.readthedocs.io/en/latest/api.html#asyncserver-class但是,我在 Python socket.io 中没有看到此功能: https ://python-socketio.readthedocs.io/en/latest/api.html#asyncserver-class

Can ack function be passed to Python socket.io server from clientside JS socket.io? ack函数可以从客户端 JS socket.io 传递给 Python socket.io 服务器吗? Supposed to be using the same application protocol.假设使用相同的应用程序协议。

Yes you can, have a look at the docs: https://python-socketio.readthedocs.io/en/latest/server.html#event-callbacks是的,你可以,看看文档: https : //python-socketio.readthedocs.io/en/latest/server.html#event-callbacks

From these docs:从这些文档:

When a client sends an event to the server, it can optionally provide a callback function, to be invoked as a way of acknowledgment that the server has processed the event.当客户端向服务器发送事件时,它可以选择提供回调函数,作为确认服务器已处理事件的方式调用。 While this is entirely managed by the client, the server can provide a list of values that are to be passed on to the callback function, simply by returning them from the handler function:虽然这完全由客户端管理,但服务器可以提供要传递给回调函数的值列表,只需从处理程序函数中返回它们即可:

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

Likewise, the server can request a callback function to be invoked after a client has processed an event.同样,服务器可以请求在客户端处理事件后调用回调函数。 The socketio.Server.emit() method has an optional callback argument that can be set to a callable . socketio.Server.emit() 方法有一个可选的回调参数,可以设置为 callable If this argument is given, the callable will be invoked after the client has processed the event, and any values returned by the client will be passed as arguments to this function.如果给出此参数,则在客户端处理事件后将调用可调用对象,并且客户端返回的任何值都将作为参数传递给此函数。 Using callback functions when broadcasting to multiple clients is not recommended, as the callback function will be invoked once for each client that received the message.不建议在向多个客户端广播时使用回调函数,因为每个接收到消息的客户端都会调用一次回调函数。

So:所以:

# 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控制台日志

Just to simplify the answer by Gijs Wobben:只是为了简化 Gijs Wobben 的回答:

Client side:客户端:

sio.emit("eventname",data,function ackfunc(ackval){
     console.log(ackval);
});

Server side:服务器端:

def eventname_func(sid,data):
    ...
    return ackval # This be thrown to ackfunc at client

sio.on("eventname",eventname_func)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM