Adds device-switch guardrail to handleVoiceJoin: if the user already has a voice session on a different WebSocket, that old socket receives a voice_disconnected/displaced event before the new session takes over. Also binds voiceWs on the caller socket in handleDmCallStart and on the acceptor socket in handleDmCallAccept.