JS: close WebSockets when killing kernels

by calling Kernel.stop_channels() in Session.delete and Kernel.kill.

Changing the kernel spec deletes and creates a new session, which previously left the old WebSockets open. This could lead to FD exhaustion in the server if done several times on a given notebook.

Tests included.

- [x] close websockets when killing / switching kernels
- [x] fix start/delete race condition when switching kernels
- [x] fix `'NoneType' object has no attribute 'send_multipart'` race condition when closing websockets immediately after opening htem

closes #6304