Fix heartbeat behaviour after connection failure.

Make sure socket is closed and heartbeat is not executed when no longer active.
Stop handling events if socket is closed.

Check for self.socket to ignore events on closed socket.
Remove unused variable self.fd
Make sure socket is closed after failed connection attempt.
Do not use socket.sendall() on non-blocking socket.
Define object attributes in constructor.

This prevents current and potential future KeyErrors.
Initialise connection state variables before connection attempt.

Cleanup during shutdown is less reliable if exception is thrown.