Думаю, это то, что вы ищете:
from IPython.display import Javascript
comm_ = None
def target_func(comm, msg):
global comm_
comm_ = comm # The connection you are looking for !
## Register handler for later messages
@comm.on_msg
def _recv(msg):
# Use msg['content']['data'] for the data in the message
comm.send({'echo': msg['content']['data']})
@comm.on_close
def _close(msg):
global comm_
comm_ = None
get_ipython().kernel.comm_manager.register_target('comm_target', target_func)
Javascript('''
(async () => {
const channel = await google.colab.kernel.comms.open('comm_target');
(async function() {
for await (const message of channel.messages) {
console.log(message.data)
}
})();
})()
''')
Вопреки тому, что вы делаете, он устанавливает канал связи от клиента к ядру, что, на мой взгляд, более естественно. Затем на этом этапе вы получаете постоянное соединение comm_
, которое можно использовать для отправки сообщений на интерфейс javascript:
comm_.send(data="test")
Также можно получить список всех открытых подключений, выполняющих:
get_ipython().kernel.comm_manager.comms
Таким образом, можно избавиться от уродливой глобальной переменной и вместо этого отслеживать изменение этого атрибута. Его также можно использовать, например, для ожидания установления соединения.
Обратите внимание, что в случае Jupyter Notebook код Python такой же, но не код Javascript. Вот соответствующая реализация:
const channel = await Jupyter.notebook.kernel.comm_manager.new_comm('comm_target')
channel.on_msg(function(message) {
console.log(message.content.data);
});