question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[eventlet] how to socket.emit from the callback function

See original GitHub issue

Hi @miguelgrinberg I hope you are fill ok

Project description I’m currently building an application to visualization pressing key pianino for handling midi adapter I’m using this lib rtmidi.

for practice, my python skill I pickup to create a midi-adapter on python and via socket connect it into an angular application.

The my issue the PoC works fine, but I got a big delay in emitting so I was star searching and I found some example how to implement the eventlet and on this key testing via using setup_midi_port_mock and setup_midi_port_mock_5_keys looks pretty good but emit from callback stop working 😭

POC project as I mentioned before I got a big delay | this screnshot is for this setup on def init: setup_midi_port_mock_5_keys

left time is from the client after receive right side is from python server image

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
python-rtmidi = "*"
flask = "*"
flask-socketio = "*"

[requires]
python_version = "3.6"
from flask import Flask
from flask_socketio import SocketIO
import rtmidi
from datetime import datetime
'''
 Setup Socket IO
'''

app = Flask(__name__)
socket = SocketIO(app, logger=True, engineio_logger=True, cors_allowed_origins="*")
# app.debug = True
# app.host = '0.0.0.0'

'''
    Setup midiIn
'''
midiIn = rtmidi.MidiIn()




@socket.on('init')
def init(data):
    setup_midi_port()
    # setup_midi_port_mock()
    # setup_midi_port_mock_5_keys()


def rise_key(data):
    emit_data = {
        'action': data[0][0],
        'key': data[0][1],
        'emphasis': data[0][2],
        'duration': data[1],
        'time': datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
    }
    socket.emit('rise-key', emit_data, broadcast=True, namespace='/')
    socket.sleep(0.0001)


def click_key(data):
    emit_data = {
        'action': data[0][0],
        'key': data[0][1],
        'emphasis': data[0][2],
        'duration': data[1],
        'time': datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
    }
    socket.emit('click-key', emit_data, broadcast=True, namespace='/')
    socket.sleep(0.0001)



def setup_midi_port():
    available_ports_in = midiIn.get_ports()
    if available_ports_in:
        midiIn.close_port()
        print('Setup midi call back')
        midiIn.open_port(0)
        midiIn.set_callback(lambda data, time: rise_key(data) if data[0][0] == 128 else click_key(data))

def setup_midi_port_mock():
    loop = 20
    while True:
        loop = 21 if loop == 109 else loop + 1
        click_key(([144, loop, 64], 0.009))
        rise_key(([128,loop,64], 0.009))


def setup_midi_port_mock_5_keys():
    while True:

        click_key(([144, 61, 64], 0.009))
        click_key(([144, 62, 64], 0.009))
        click_key(([144, 63, 64], 0.009))
        click_key(([144, 64, 64], 0.009))
        click_key(([144, 65, 64], 0.009))

        socket.sleep(0.1)

        rise_key(([128, 65, 64], 0.009))
        rise_key(([128, 64, 64], 0.009))
        rise_key(([128, 63, 64], 0.009))
        rise_key(([128, 62, 64], 0.009))
        rise_key(([128, 61, 64], 0.009))

        socket.sleep(0.1)

if __name__ == '__main__':
    socket.run(app, host = '127.0.0.1')

**Project with eventlet ** as I mentioned before in this case for below option everything is working properly without any troubles and animation lags on angular application eventlet.spawn(setup_midi_port_mock) eventlet.spawn(setup_midi_port_mock_5_keys)

but 😭 but this configuration eventlet.spawn(setup_midi_port) is not working. more information you will find under code

[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true

[dev-packages]

[packages]
python-rtmidi = "*"
flask = "*"
flask-socketio = "*"
eventlet = "*"

[requires]
python_version = "3.6"
import eventlet
eventlet.monkey_patch()
from flask import Flask
from flask_socketio import SocketIO
import rtmidi
from datetime import datetime

app = Flask(__name__)
socket = SocketIO(app, logger=True, engineio_logger=True, cors_allowed_origins="*")

'''
    Setup midiIn
'''
midiIn = rtmidi.MidiIn()


@socket.on('init')
def init(data):
    eventlet.spawn(setup_midi_port)
    #eventlet.spawn(setup_midi_port_mock)
    #eventlet.spawn(setup_midi_port_mock_5_keys)


def rise_key(data):
    emit_data = {
        'action': data[0][0],
        'key': data[0][1],
        'emphasis': data[0][2],
        'duration': data[1],
        'time': datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
    }
    socket.emit('rise-key', emit_data, broadcast=True, namespace='/')
    eventlet.sleep(0)


def click_key(data):
    emit_data = {
        'action': data[0][0],
        'key': data[0][1],
        'emphasis': data[0][2],
        'duration': data[1],
        'time': datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]
    }
    socket.emit('click-key', emit_data, broadcast=True, namespace='/')
    eventlet.sleep(0)


def setup_midi_port():

    available_ports_in = midiIn.get_ports()
    if available_ports_in:
        midiIn.close_port()
        print('Setup midi call back')
        midiIn.open_port(0)
        midiIn.set_callback(lambda data, time: rise_key(data) if data[0][0] == 128 else click_key(data))


'''
    Working without any lags, animations are perfect
'''
def setup_midi_port_mock():
    loop = 20
    while True:
        loop = 21 if loop == 109 else loop + 1
        click_key(([144, loop, 64], 0.009))
        rise_key(([128,loop,64], 0.009))


'''
    Working without any lags, animations are perfect
    after emit eventlet.sleep(0) is set to 0 to imit human press all
'''
def setup_midi_port_mock_5_keys():
    while True:

        click_key(([144, 61, 64], 0.009))
        click_key(([144, 62, 64], 0.009))
        click_key(([144, 63, 64], 0.009))
        click_key(([144, 64, 64], 0.009))
        click_key(([144, 65, 64], 0.009))

        eventlet.sleep(0.1)

        rise_key(([128, 65, 64], 0.009))
        rise_key(([128, 64, 64], 0.009))
        rise_key(([128, 63, 64], 0.009))
        rise_key(([128, 62, 64], 0.009))
        rise_key(([128, 61, 64], 0.009))

        eventlet.sleep(0.1)


if __name__ == '__main__':
    socket.run(app, host='127.0.0.1')

so what is occured for eventlet.spawn(setup_midi_port)

Logs after launch application and call @socket.on(‘init’) image

Logs after press key on keyboard image

From logs, it looks like everything is ok, but UI doesn’t get any message, after play some times I got this logs (Yes I know the session is not the same as on previous images 😉, but the issue occurred before too and this I’ve made after restart everything)

image

I hope you have some idea how to modify it 😉 Thanks in advance

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

0reactions
LaionFromNightcommented, Jun 15, 2020

Yes, I think for now in peer to peer communication this limitation is acceptable.

Thanks in tone.

Read more comments on GitHub >

github_iconTop Results From Across the Web

(flask + socket.IO) Result of emit callback is the response of ...
If you want to emit to one client (hopefully not the same one that sent the HTTP request), then you need to add...
Read more >
The Socket.IO Server — python-socketio documentation
The socketio. Server. emit() method has an optional callback argument that can be set to a callable. If this argument is given, the...
Read more >
Quick Socket.IO Tutorial, Part 5: Callbacks - YouTube
... for this video: https://github.com/miguelgrinberg/quick-socketio-tutorial/tree/part5. ... Quick Socket. IO Tutorial, Part 5: Callbacks.
Read more >
Flask-SocketIO Documentation - manpages.ubuntu!
SocketIO event handlers defined as shown in the previous section can send reply messages to the connected client using the send() and emit()...
Read more >
rust_socketio - crates.io: Rust Package Registry
use rust_socketio::{SocketBuilder, Payload, Socket}; use serde_json::json; use std::time::Duration; // define a callback which is called ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found