Instead of throwing and crashing the gateway when MySQL connection
fails, close the broken pool and continue with pool=null so the
isAvailable() guard handles it gracefully.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
handleSend() only checked socket-based devices (deviceToSocket map),
causing DEVICE_NOT_FOUND errors when Hub sends responses to virtual
devices like Telegram. Now checks virtualDevices map as fallback.
Also adds routeFromVirtualDevice() to allow virtual devices to
initiate messages (e.g., verify RPC, chat messages) through the
Gateway routing infrastructure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>