jupyter notebook的通信

作者: gg5d | 来源:发表于2017-12-03 20:29 被阅读0次

    提示用户输入一段代码,当用户输入以后执行。这种模式经常被称为REPL(交互式开发环境),或者Read-Eval-Print-Loop(读取﹣求值﹣输出循环).jupyter notebook就是这样一种在web端的交互式开发环境,如下:


    jupyter notebook示例

    对应.ipynb文件的内容:

    {
     "cells": [
      {
       "cell_type": "code",
       "execution_count": 1,
       "metadata": {
        "collapsed": false
       },
       "outputs": [
        {
         "name": "stdout",
         "output_type": "stream",
         "text": [
          "pi is rough3.142608\n"
         ]
        }
       ],
       "source": [
        "import scala.math.random\n",
        "import org.apache.spark._\n",
        "val slices = 10\n",
        "val n = math.min(100000L * slices, Int.MaxValue).toInt\n",
        "val count = sc.parallelize(1 until n, slices).map{ i =>\n",
        "                                                val x = random*2 - 1\n",
        "                                                val y = random*2 -1\n",
        "                                                if (x*x + y*y <1) 1 else 0\n",
        "                                                }.reduce(_+_)\n",
        "println(\"pi is rough\" + 4.0*count/n)"
       ]
      }
     ],
     "metadata": {
      "anaconda-cloud": {},
      "kernelspec": {
       "display_name": "Apache Toree - Scala",
       "language": "scala",
       "name": "apache_toree_scala"
      },
      "language_info": {
       "name": "scala",
       "version": "2.11.8"
      }
     },
     "nbformat": 4,
     "nbformat_minor": 1
    }
    

    IPython 内核 所有其它接口,包括Notebook,Qt控制台,ipython控制台和其它第三方接口,都使用IPython内核。IPython内核是一个独立的进程,负责执行用户代码和其它事情,例如计算可能的补全。前端处理器,例如notebook和Qt控制台,使用ZeroMQ传输JSON消息与IPython内核通信,前端处理器与IPython内核通信使用的协议详细描述请参考Jupyter 消息

    notebook简单通信图

    Notebook 前端处理器做一些额外的事情。除了运行你的代码,它还储存代码和输出、以及markdown注释在一个可编辑的文档中,我们称这个文档为一个notebook。当你保存这个文档时,它会从你的浏览器发送到notebook服务器,服务器将文档保存为.ipynb为拓展名的JSON格式文件,notebook服务器而不是内核,负责保存和载入notebook,因此你可以编辑notebook即使你没有那种编程语言的内核,你仅仅不能运行notebook中的代码。内核不知道notebook文档任何事情,它只是在用户运行代码时获取用户发送的代码并执行。导出notebooks到其他格式 Jupyter中的工具Nbconvert可以将notebook文件转换到其它格式,例如HTML,LaTex.
    使用nbconvert和HTML导出器。当你输入一个网址,它从输入的网址获取notebook,然后将其转换为HTML格式,并将HTML呈现给你。

    jupyter
    Python Notebook中输入的代码经由浏览器发送给Web服务器,再由Web服务器发送消息到IPython的Kernel执行代码,在Kernel中执行代码所产生的输出会再发送给Web服务器从而发送给浏览器,完成整个运行过程。Web服务器和Kernel之间采用ZeroMQ进行通信。下面为其通信的示意图:
    通信示意图
    图中,Kernel经由绿色的DEAL-ROUTER通道接收来自Web服务器的命令消息,并返回应答消息。通过红色的PUB-SUB通道传输被执行代码所产生的输出信息。
    在Kernel中,用户代码在一个用户环境(字典)中执行,通常无法获得关于Kernel的信息。但是由于用户代码和Kernel在同一进程中执行,因此我们可以通过一些特殊的代码研究Kernel是如何接收、运行并返回消息的。
    两种思路:
    一、从websocket入手
    打开一个新的notebook: http://127.0.0.1:5000/notebooks/Untitled1.ipynb
    从chrome调试面板的Network可以看到,有个websocket:ws://127.0.0.1:5000/api/kernels/d13a50b0-6baa-4d5e-8564-95f224daxxxx/channels?session_id=F552491A7C0448A2B5567DE1A71Cxxxx,代码经由它往后端发送,也经由它接收后台返回的信息
    当我们运行上头的print("hello world")时,往后台发送如下数据
    {
    "header":
    {
    "msg_id":"D8FA79DCD7D140DF8F9C37EE15D9FD6D",
    "username":"username",
    "session":"91608A811CAE4FA6A5E09D37AF68DF32",
    "msg_type":"execute_request",
    "version":"5.0"
    },
    "metadata":{},
    "content":
    {
    "code":"print(\"hello world\")",
    "silent":false,
    "store_history":true,
    "user_expressions":{},
    "allow_stdin":true,
    "stop_on_error":true
    },
    "buffers":[],
    "parent_header":{},
    "channel":"shell"
    }
    

    接下来有5个frames:

    {
    "parent_header": 
    {
    "username": "username",
     "session": "91608A811CAE4FA6A5E09D37AF68DF32", 
    "version": "5.0",
     "msg_id": "D8FA79DCD7D140DF8F9C37EE15D9FD6D",
     "msg_type": "execute_request"
    }, 
    "msg_type": "status",
     "msg_id": "ce11828e-1c2a-4254-962f-2db9e2ff3353", 
    "content": 
    {
    "execution_state": "busy"
    }, 
    "header": 
    {
    "username": "root",
     "version": "5.0", 
    "msg_type": "status",
     "msg_id": "ce11828e-1c2a-4254-962f-2db9e2ff3353", 
    "session": "604a11a4-14eb-4f8a-b32d-044d4c195bf3",
     "date": "2017-12-03T20:05:06.816757"
    }, 
    "channel": "iopub",
     "buffers": [], 
    "metadata": 
    {
    "timestamp": "1512302706811"
    }
    }
    
    {
    "parent_header":
     {
    "username": "username", 
    "session": "91608A811CAE4FA6A5E09D37AF68DF32", 
    "version": "5.0",
     "msg_id": "D8FA79DCD7D140DF8F9C37EE15D9FD6D",
     "msg_type": "execute_request"
    }, 
    "msg_type": "execute_input",
     "msg_id": "116696e7-befa-40c7-98c1-88e32e1e9b63",
     "content": 
    {
    "execution_count": 1, 
    "code": "print(\"hello world\")"
    }, 
    "header":
     {
    "username": "root",
     "version": "5.0",
     "msg_type": "execute_input",
     "msg_id": "116696e7-befa-40c7-98c1-88e32e1e9b63", 
    "session": "604a11a4-14eb-4f8a-b32d-044d4c195bf3", 
    "date": "2017-12-03T20:05:06.829865"
    }, 
    "channel": "iopub", 
    "buffers": [],
     "metadata": 
    {
    "timestamp": "1512302706826"
    }
    }
    
    {
    "parent_header": 
    {
    "username": "username",
     "session": "91608A811CAE4FA6A5E09D37AF68DF32", 
    "version": "5.0", "msg_id": "D8FA79DCD7D140DF8F9C37EE15D9FD6D", 
    "msg_type": "execute_request"
    }, 
    "msg_type": "stream",
     "msg_id": "d3c9ffa1-108f-4ea2-88db-100985fe23d0",
     "content": 
    {
    "text": "hello world", "name": "stdout"
    }, 
    "header": 
    {
    "username": "root", 
    "version": "5.0", 
    "msg_type": "stream",
     "msg_id": "d3c9ffa1-108f-4ea2-88db-100985fe23d0",
     "session": "604a11a4-14eb-4f8a-b32d-044d4c195bf3", 
    "date": "2017-12-03T20:05:07.071811"
    }, 
    "channel": "iopub",
     "buffers": [],
     "metadata": 
    {
    "timestamp": "1512302707065"
    }
    }
    
    {
    "parent_header":
     {
    "username": "username", 
    "session": "91608A811CAE4FA6A5E09D37AF68DF32",
     "version": "5.0", 
    "msg_id": "D8FA79DCD7D140DF8F9C37EE15D9FD6D",
     "msg_type": "execute_request"
    },
     "msg_type": "execute_reply",
     "msg_id": "6ee99d0d-9c92-41ce-be06-39241719f321",
     "content": 
    {
    "status": "ok", 
    "execution_count": 1, 
    "payload": [],
     "user_expressions": {}
    }, 
    "header":
     {
    "username": "root",
     "version": "5.0",
     "msg_type": "execute_reply",
     "msg_id": "6ee99d0d-9c92-41ce-be06-39241719f321",
     "session": "604a11a4-14eb-4f8a-b32d-044d4c195bf3",
     "date": "2017-12-03T20:05:07.097685"
    }, 
    "channel": "shell",
     "buffers": [], 
    "metadata": 
    {
    "timestamp": "1512302707094"
    }
    }
    
    {
    "parent_header": 
    {
    "username": "username",
     "session": "91608A811CAE4FA6A5E09D37AF68DF32",
     "version": "5.0",
     "msg_id": "D8FA79DCD7D140DF8F9C37EE15D9FD6D", 
    "msg_type": "execute_request"
    }, 
    "msg_type": "status",
     "msg_id": "32857f80-db87-4775-9350-fe009a8e9c18",
     "content": {
    "execution_state": "idle"
    }, 
    "header":
     {
    "username": "root", 
    "version": "5.0", 
    "msg_type": "status",
     "msg_id": "32857f80-db87-4775-9350-fe009a8e9c18",
     "session": "604a11a4-14eb-4f8a-b32d-044d4c195bf3", 
    "date": "2017-12-03T20:05:07.098384"
    },
     "channel": "iopub",
     "buffers": [], 
    "metadata": 
    {
    "timestamp": "1512302707095"
    }
    }
    
    chrome/Network/WS/Frames

    在支持WebSocket的浏览器中,在创建socket之后。可以通过onopen,onmessage,onclose和onerror四个事件实现对socket进行响应

    一个简单的 示例

    var ws = new WebSocket(“ws://localhost:8080”);
    
    ws.onopen = function()
    
    {  console.log(“open”);
    
      ws.send(“hello”);
    
    };
    
    ws.onmessage = function(evt)
    
    {
    
      console.log(evt.data)
    
    };
    
    ws.onclose = function(evt)
    
    {
    
      console.log(“WebSocketClosed!”);
    
    };
    
    ws.onerror = function(evt)
    
    {
    
      console.log(“WebSocketError!”);
    
    };
    

    1.var ws = new WebSocket(“ws://localhost:8080”);

    申请一个WebSocket对象,参数是需要连接的服务器端的地址,同http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,另外安全的WebSocket协议使用wss://开头。

    ws.send(“hello”);
    用于将消息发送到服务端
    2.ws.onopen = function() { console.log(“open”)};

    当websocket创建成功时,即会触发onopen事件
    3.ws.onmessage = function(evt) { console.log(evt.data) };
    当客户端收到服务端发来的消息时,会触发onmessage事件,参数evt.data中包含server传输过来的数据
    4.ws.onclose = function(evt) { console.log(“WebSocketClosed!”); };

    当客户端收到服务端发送的关闭连接的请求时,触发onclose事件
    5.ws.onerror = function(evt) { console.log(“WebSocketError!”); };
    如果出现连接,处理,接收,发送数据失败的时候就会触发onerror事件
    我们可以看出所有的操作都是采用事件的方式触发的,这样就不会阻塞UI,使得UI有更快的响应时间,得到更好的用户体验。
    二、从页面入手
    在stack overflow里找到解答:

    var handle_output = function (data) {console.log(data);}
    //callbacks.iopub.output is used to get the data from execute
    var callbacks = {
                iopub : {output : handle_output,}
    }
    //(read the source F12->static/notebook/js/services/kernels/kernel.js)
    //kernel.js/717th lines Kernel.prototype.execute
    var kernel = IPython.notebook.kernel;
    kernel.execute("print('hello')",callbacks)
    

    kernel.js的function:

    // Copyright (c) Jupyter Development Team.
    // Distributed under the terms of the Modified BSD License.
    define('services/kernels/kernel',[
        'jquery',
        'base/js/utils',
        './comm',
        './serialize',
        'base/js/events'
    ], function($, utils, comm, serialize, events) {
        "use strict";
    
        /**
         * A Kernel class to communicate with the Python kernel. This
         * should generally not be constructed directly, but be created
         * by.  the `Session` object. Once created, this object should be
         * used to communicate with the kernel.
         * 
         * Preliminary documentation for the REST API is at
         * https://github.com/ipython/ipython/wiki/IPEP-16%3A-Notebook-multi-directory-dashboard-and-URL-mapping#kernels-api
         * 
         * @class Kernel
         * @param {string} kernel_service_url - the URL to access the kernel REST api
         * @param {string} ws_url - the websockets URL
         * @param {string} name - the kernel type (e.g. python3)
         */
        var Kernel = function (kernel_service_url, ws_url, name) {
            this.events = events;
    
            this.id = null;
            this.name = name;
            this.ws = null;
    
            this.kernel_service_url = kernel_service_url;
            this.kernel_url = null;
            this.ws_url = ws_url || utils.get_body_data("wsUrl");
            if (!this.ws_url) {
                // trailing 's' in https will become wss for secure web sockets
                this.ws_url = location.protocol.replace('http', 'ws') + "//" + location.host;
            }
    
            this.username = "username";
            this.session_id = utils.uuid();
            this._msg_callbacks = {};
            this._msg_queue = Promise.resolve();
            this.info_reply = {}; // kernel_info_reply stored here after starting
    
            if (typeof(WebSocket) !== 'undefined') {
                this.WebSocket = WebSocket;
            } else if (typeof(MozWebSocket) !== 'undefined') {
                this.WebSocket = MozWebSocket;
            } else {
                alert('Your browser does not have WebSocket support, please try Chrome, Safari or Firefox ≥ 6. Firefox 4 and 5 are also supported by you have to enable WebSockets in about:config.');
            }
            
            this.bind_events();
            this.init_iopub_handlers();
            this.comm_manager = new comm.CommManager(this);
            
            this.last_msg_id = null;
            this.last_msg_callbacks = {};
    
            this._autorestart_attempt = 0;
            this._reconnect_attempt = 0;
            this.reconnect_limit = 7;
            
            this._pending_messages = [];
        };
    
        /**
         * @function _get_msg
         */
        Kernel.prototype._get_msg = function (msg_type, content, metadata, buffers) {
    
            return msg;
        };
    
        /**
         * @function bind_events
         */
        Kernel.prototype.bind_events = function () {
           
        };
    
        /**
         * Initialize the iopub handlers.
         *
         * @function init_iopub_handlers
         */
        Kernel.prototype.init_iopub_handlers = function () {
          
        };
    
        /**
         * GET /api/kernels
         *
         * Get the list of running kernels.
         *
         * @function list
         * @param {function} [success] - function executed on ajax success
         * @param {function} [error] - functon executed on ajax error
         */
        Kernel.prototype.list = function (success, error) {
        
        };
    
        /**
         * POST /api/kernels
         *
         * Start a new kernel.
         *
         * In general this shouldn't be used -- the kernel should be
         * started through the session API. If you use this function and
         * are also using the session API then your session and kernel
         * WILL be out of sync!
         *
         * @function start
         * @param {params} [Object] - parameters to include in the query string
         * @param {function} [success] - function executed on ajax success
         * @param {function} [error] - functon executed on ajax error
         */
        Kernel.prototype.start = function (params, success, error) {
            return url;
        };
    
        /**
         * GET /api/kernels/[:kernel_id]
         *
         * Get information about the kernel.
         *
         * @function get_info
         * @param {function} [success] - function executed on ajax success
         * @param {function} [error] - functon executed on ajax error
         */
        Kernel.prototype.get_info = function (success, error) {
        };
    
        /**
         * DELETE /api/kernels/[:kernel_id]
         *
         * Shutdown the kernel.
         *
         * If you are also using sessions, then this function shoul NOT be
         * used. Instead, use Session.delete. Otherwise, the session and
         * kernel WILL be out of sync.
         *
         * @function kill
         * @param {function} [success] - function executed on ajax success
         * @param {function} [error] - functon executed on ajax error
         */
        Kernel.prototype.kill = function (success, error) {
    
        };
    
        /**
         * POST /api/kernels/[:kernel_id]/interrupt
         *
         * Interrupt the kernel.
         *
         * @function interrupt
         * @param {function} [success] - function executed on ajax success
         * @param {function} [error] - functon executed on ajax error
         */
        Kernel.prototype.interrupt = function (success, error) {
    
        };
    
        Kernel.prototype.restart = function (success, error) {
            /**
             * POST /api/kernels/[:kernel_id]/restart
             *
             * Restart the kernel.
             *
             * @function interrupt
             * @param {function} [success] - function executed on ajax success
             * @param {function} [error] - functon executed on ajax error
             */
    
        };
    
        Kernel.prototype.reconnect = function () {
    
        };
    
        Kernel.prototype._on_success = function (success) {
            /**
             * Handle a successful AJAX request by updating the kernel id and
             * name from the response, and then optionally calling a provided
             * callback.
             *
             * @function _on_success
             * @param {function} success - callback
             */
    
        };
    
        Kernel.prototype._on_error = function (error) {
            /**
             * Handle a failed AJAX request by logging the error message, and
             * then optionally calling a provided callback.
             *
             * @function _on_error
             * @param {function} error - callback
             */
    
        };
    
        Kernel.prototype._kernel_created = function (data) {
            /**
             * Perform necessary tasks once the kernel has been started,
             * including actually connecting to the kernel.
             *
             * @function _kernel_created
             * @param {Object} data - information about the kernel including id
             */
    
        };
    
        Kernel.prototype._kernel_connected = function () {
            /**
             * Perform necessary tasks once the connection to the kernel has
             * been established. This includes requesting information about
             * the kernel.
             *
             * @function _kernel_connected
             */
    
        };
    
        Kernel.prototype._kernel_dead = function () {
            /**
             * Perform necessary tasks after the kernel has died. This closing
             * communication channels to the kernel if they are still somehow
             * open.
             *
             * @function _kernel_dead
             */
    
        };
    
        Kernel.prototype.start_channels = function () {
            /**
             * Start the websocket channels.
             * Will stop and restart them if they already exist.
             *
             * @function start_channels
             */
        };
    
        Kernel.prototype._ws_opened = function (evt) {
            /**
             * Handle a websocket entering the open state,
             * signaling that the kernel is connected when websocket is open.
             *
             * @function _ws_opened
             */
    
        };
    
        Kernel.prototype._ws_closed = function(ws_url, error) {
            /**
             * Handle a websocket entering the closed state.  If the websocket
             * was not closed due to an error, try to reconnect to the kernel.
             *
             * @function _ws_closed
             * @param {string} ws_url - the websocket url
             * @param {bool} error - whether the connection was closed due to an error
             */
    
        };
        
        Kernel.prototype._schedule_reconnect = function () {
            /**
             * function to call when kernel connection is lost
             * schedules reconnect, or fires 'connection_dead' if reconnect limit is hit
             */
    
        };
        
        Kernel.prototype.stop_channels = function () {
            /**
             * Close the websocket. After successful close, the value
             * in `this.ws` will be null.
             *
             * @function stop_channels
             */
    
        };
    
        Kernel.prototype.is_connected = function () {
            /**
             * Check whether there is a connection to the kernel. This
             * function only returns true if websocket has been
             * created and has a state of WebSocket.OPEN.
             *
             * @function is_connected
             * @returns {bool} - whether there is a connection
             */
            // if any channel is not ready, then we're not connected
    
        };
    
        Kernel.prototype.is_fully_disconnected = function () {
            /**
             * Check whether the connection to the kernel has been completely
             * severed. This function only returns true if all channel objects
             * are null.
             *
             * @function is_fully_disconnected
             * @returns {bool} - whether the kernel is fully disconnected
             */
            return (this.ws === null);
        };
        
        Kernel.prototype._send = function(msg) {
          /**
           * Send a message (if the kernel is connected) or queue the message for future delivery
           *
           * Pending messages will automatically be sent when a kernel becomes connected.
           *
           * @function _send
           * @param msg
           */
    
        }
        
        Kernel.prototype.send_shell_message = function (msg_type, content, callbacks, metadata, buffers) {
            /**
             * Send a message on the Kernel's shell channel
             *
             * If the kernel is not connected, the message will be buffered.
             * 
             * @function send_shell_message
             */
            return msg.header.msg_id;
        };
    
        Kernel.prototype.kernel_info = function (callback) {
            /**
             * Get kernel info
             *
             * @function kernel_info
             * @param callback {function}
             *
             * When calling this method, pass a callback function that expects one argument.
             * The callback will be passed the complete `kernel_info_reply` message documented
             * [here](https://jupyter-client.readthedocs.io/en/latest/messaging.html#kernel-info)
             */
        };
    
        Kernel.prototype.comm_info = function (target_name, callback) {
            /**
             * Get comm info
             *
             * @function comm_info
             * @param callback {function}
             *
             * When calling this method, pass a callback function that expects one argument.
             * The callback will be passed the complete `comm_info_reply` message documented
             * [here](https://jupyter-client.readthedocs.io/en/latest/messaging.html#comm_info)
             */
    
        };
    
        Kernel.prototype.inspect = function (code, cursor_pos, callback) {
            /**
             * Get info on an object
             *
             * When calling this method, pass a callback function that expects one argument.
             * The callback will be passed the complete `inspect_reply` message documented
             * [here](https://jupyter-client.readthedocs.io/en/latest/messaging.html#object-information)
             *
             * @function inspect
             * @param code {string}
             * @param cursor_pos {integer}
             * @param callback {function}
             */
    
        };
    
        Kernel.prototype.execute = function (code, callbacks, options) {
            /**
             * Execute given code into kernel, and pass result to callback.
             *
             * @async
             * @function execute
             * @param {string} code
             * @param [callbacks] {Object} With the following keys (all optional)
             *      @param callbacks.shell.reply {function}
             *      @param callbacks.shell.payload.[payload_name] {function}
             *      @param callbacks.iopub.output {function}
             *      @param callbacks.iopub.clear_output {function}
             *      @param callbacks.input {function}
             * @param {object} [options]
             *      @param [options.silent=false] {Boolean}
             *      @param [options.user_expressions=empty_dict] {Dict}
             *      @param [options.allow_stdin=false] {Boolean} true|false
             *
             * @example
             *
             * The options object should contain the options for the execute
             * call. Its default values are:
             *
             *      options = {
             *        silent : true,
             *        user_expressions : {},
             *        allow_stdin : false
             *      }
             *
             * When calling this method pass a callbacks structure of the
             * form:
             *
             *      callbacks = {
             *       shell : {
             *         reply : execute_reply_callback,
             *         payload : {
             *           set_next_input : set_next_input_callback,
             *         }
             *       },
             *       iopub : {
             *         output : output_callback,
             *         clear_output : clear_output_callback,
             *       },
             *       input : raw_input_callback
             *      }
             *
             * Each callback will be passed the entire message as a single
             * arugment.  Payload handlers will be passed the corresponding
             * payload and the execute_reply message.
             */
            return this.send_shell_message("execute_request", content, callbacks);
        };
    
        /**
         * When calling this method, pass a function to be called with the
         * `complete_reply` message as its only argument when it arrives.
         *
         * `complete_reply` is documented
         * [here](https://jupyter-client.readthedocs.io/en/latest/messaging.html#complete)
         *
         * @function complete
         * @param code {string}
         * @param cursor_pos {integer}
         * @param callback {function}
         */
        Kernel.prototype.complete = function (code, cursor_pos, callback) {
    
            return this.send_shell_message("complete_request", content, callbacks);
        };
    
        /**
         * @function send_input_reply
         */
        Kernel.prototype.send_input_reply = function (input) {
            return msg.header.msg_id;
        };
    
        /**
         * @function register_iopub_handler
         */
        Kernel.prototype.register_iopub_handler = function (msg_type, callback) {
            this._iopub_handlers[msg_type] = callback;
        };
    
        /**
         * Get the iopub handler for a specific message type.
         *
         * @function get_iopub_handler
         */
        Kernel.prototype.get_iopub_handler = function (msg_type) {
            return this._iopub_handlers[msg_type];
        };
    
        /**
         * Get callbacks for a specific message.
         *
         * @function get_callbacks_for_msg
         */
        Kernel.prototype.get_callbacks_for_msg = function (msg_id) {
    
        };
    
        /**
         * Clear callbacks for a specific message.
         *
         * @function clear_callbacks_for_msg
         */
        Kernel.prototype.clear_callbacks_for_msg = function (msg_id) {
            if (this._msg_callbacks[msg_id] !== undefined ) {
                delete this._msg_callbacks[msg_id];
            }
        };
        
        /**
         * @function _finish_shell
         */
        Kernel.prototype._finish_shell = function (msg_id) {
    
        };
    
        /**
         * @function _finish_iopub
         */
        Kernel.prototype._finish_iopub = function (msg_id) {
    
        };
        
        /**
         * Set callbacks for a particular message.
         * Callbacks should be a struct of the following form:
         * shell : {
         * 
         * }
         *
         * @function set_callbacks_for_msg
         */
        Kernel.prototype.set_callbacks_for_msg = function (msg_id, callbacks) {
    
        };
        
        Kernel.prototype._handle_ws_message = function (e) {
    
        };
    
        Kernel.prototype._finish_ws_message = function (msg) {
    
        };
        
        Kernel.prototype._handle_shell_reply = function (reply) {
            return promise;
        };
    
        /**
         * @function _handle_payloads
         */
        Kernel.prototype._handle_payloads = function (payloads, payload_callbacks, msg) {
            return Promise.all(promise);
        };
    
        /**
         * @function _handle_status_message
         */
        Kernel.prototype._handle_status_message = function (msg) {
           
        };
        
        /**
         * Handle clear_output message
         *
         * @function _handle_clear_output
         */
        Kernel.prototype._handle_clear_output = function (msg) {
    
        };
    
        /**
         * handle an output message (execute_result, display_data, etc.)
         *
         * @function _handle_output_message
         */
        Kernel.prototype._handle_output_message = function (msg) {
    
        };
    
        /**
         * Handle an input message (execute_input).
         *
         * @function _handle_input message
         */
        Kernel.prototype._handle_input_message = function (msg) {
    
        };
    
        /**
         * Dispatch IOPub messages to respective handlers. Each message
         * type should have a handler.
         *
         * @function _handle_iopub_message
         */
        Kernel.prototype._handle_iopub_message = function (msg) {
    
        };
    
        /**
         * @function _handle_input_request
         */
        Kernel.prototype._handle_input_request = function (request) {
    
        };
    
        return {'Kernel': Kernel};
    });
    

    参考文章:
    http://blog.just4fun.site/jupyter-notebook-architecture.html
    http://blog.just4fun.site/jupyter-notebook-architecture-hack.html
    https://www.tuicool.com/articles/naqIza
    http://flamepeak.com/2016/09/12/Jupyter-official-docs-translate-20160912/
    https://jupyter-client.readthedocs.io/en/latest/messaging.html#messaging
    http://jupyter-notebook.readthedocs.io/en/stable/comms.html
    http://hyry.dip.jp/tech/slice/slice.html/36
    http://jupyter-notebook.readthedocs.io/en/stable/examples/Notebook/Connecting%20with%20the%20Qt%20Console.html?highlight=messaging#The-Frontend/Kernel-Model
    https://github.com/junjunwudi/zmq-pykernel
    https://media.readthedocs.org/pdf/jupyter-notebook/4.x/jupyter-notebook.pdf
    https://github.com/ipython/ipython/wiki/IPEP-16%3A-Notebook-multi-directory-dashboard-and-URL-mapping#create_new_notebook
    https://stackoverflow.com/questions/26435653/how-do-i-embed-an-ipython-notebook-in-an-iframe-new
    http://www.tornadoweb.org/en/stable/web.html#request-handlers
    http://jupyter-client.readthedocs.io/en/latest/messaging.html#custom-messages
    http://jupyter-notebook.readthedocs.io/en/latest/extending/handlers.html
    http://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter/notebook/master/notebook/services/api/api.yaml
    http://Check.torproject.org
    https://gist.github.com/disarticulate/d06069ff3e71cf828e5329beab8cb084
    https://stackoverflow.com/questions/31357718/ipython-javascript-client-api/42418784#42418784
    https://www.cnblogs.com/lxtblogs/p/4947898.html
    http://jupyter-client.readthedocs.io/en/latest/messaging.html
    http://jupyter-notebook.readthedocs.io/en/latest/frontend_config.html#configuring-the-notebook-frontend
    http://ipython.org/ipython-doc/stable/development/messaging.html

    相关文章

      网友评论

        本文标题:jupyter notebook的通信

        本文链接:https://www.haomeiwen.com/subject/draabxtx.html