JS: close WebSockets when killing kernels

by calling Kernel.stop_channels() in Session.delete and Kernel.kill
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

I think it's still possible to get to a state with no kernel and insufficient indication.
Imperfect, but an improvement.
Merge pull request #6305 from minrk/switch-kernel-close-ws

JS: close WebSockets when killing kernels