private void EventLoop(NetMQSocket socket) { this.logger.LogDebug("Starting shell server event loop at {Address}.", socket); while (alive) { try { // Start by pulling off the next <action>_request message // from the client. var nextMessage = socket.ReceiveMessage(context); logger.LogDebug( $"Received new message:\n" + $"\t{JsonConvert.SerializeObject(nextMessage.Header)}\n" + $"\t{JsonConvert.SerializeObject(nextMessage.ParentHeader)}\n" + $"\t{JsonConvert.SerializeObject(nextMessage.Metadata)}\n" + $"\t{JsonConvert.SerializeObject(nextMessage.Content)}" ); // If this is our first message, we need to set the session // id. if (session == null) { session = nextMessage.Header.Session; } // Get a service that can handle the message type and // dispatch. switch (nextMessage.Header.MessageType) { case "kernel_info_request": KernelInfoRequest?.Invoke(nextMessage); break; case "execute_request": ExecuteRequest?.Invoke(nextMessage); break; case "shutdown_request": ShutdownRequest?.Invoke(nextMessage); break; } } catch (ProtocolViolationException ex) { logger.LogCritical(ex, $"Protocol violation when trying to receive next ZeroMQ message."); } catch (ThreadInterruptedException) { if (alive) { continue; } else { return; } } } }
public ShellServer( ILogger <ShellServer> logger, IOptions <KernelContext> context, IServiceProvider provider, IShellRouter router ) { this.logger = logger; this.context = context.Value; this.provider = provider; this.router = router; router.RegisterHandler("kernel_info_request", async message => KernelInfoRequest?.Invoke(message)); router.RegisterHandler("shutdown_request", async message => ShutdownRequest?.Invoke(message)); }
/// <summary> /// Called by shell servers to report kernel information to the /// client. By default, this method responds by converting /// the kernel properties stored in this engine's context to a /// <c>kernel_info</c> Jupyter message. /// </summary> /// <param name="message">The original request from the client.</param> public virtual void OnKernelInfoRequest(Message message) { // Before handling the kernel info request, make sure to call any // events for custom handling. KernelInfoRequest?.Invoke(message); try { // Tell the client we're about to handle their kernel_info_request. this.SendIoPubMessage( new Message { Header = new MessageHeader { MessageType = "status" }, Content = new KernelStatusContent { ExecutionState = ExecutionState.Busy } } .AsReplyTo(message) ); this.SendShellMessage( new Message { ZmqIdentities = message.ZmqIdentities, ParentHeader = message.Header, Metadata = null, Content = this.context.Properties.AsKernelInfoReply(), Header = new MessageHeader { MessageType = "kernel_info_reply", Id = Guid.NewGuid().ToString(), ProtocolVersion = "5.2.0" } } ); // Once finished, have the shell server report that we are // idle. this.SendIoPubMessage( new Message { Header = new MessageHeader { MessageType = "status" }, Content = new KernelStatusContent { ExecutionState = ExecutionState.Idle } } .AsReplyTo(message) ); } catch (Exception e) { this.logger?.LogError(e, "Unable to process KernelInfoRequest"); } }