handle undefined or closed zmq_stream in on_message

can happen if a message is waiting in a pipe and the web socket is closed before the message is handled.

And give ZMQChannels a nice repr with their kernel ID
avoid race condition when deleting/starting sessions

javascript doesn't guarantee the order of AJAX requests,
so we give `Session.delete` and `Kernel.kill` a callback signature.

Changing the kernel type calls `Notebook.start_kernel`,
which terminates the previous session, if defined,
before starting the new one.

A flag is stored, to prevent multiple simultaneous attempts to start sessions, raising a SessionAlreadyStarting Error,
preventing the spec_changed event from firing.
improve indicators and handling of dead kernels and broken websocket connections

still some work to be done