class WebViewWSServer {
    private final Logger logger = LoggerFactory.getLogger(WebViewWSServer.class);
    @Value("${sonic.agent.key}")
    private String key;
    private Map<Session, WebSocketClient> sessionWebSocketClientMap = new HashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("key") String secretKey, @PathParam("port") int port, @PathParam("id") String id) throws Exception {
        if (secretKey.length() == 0 || (!secretKey.equals(key))) {
            logger.info("Auth Failed!");
            return;
        }
        URI uri = new URI("ws://localhost:" + port + "/devtools/page/" + id);
        WebSocketClient webSocketClient = new WebSocketClient(uri) {
            @Override
            public void onOpen(ServerHandshake serverHandshake) {
                logger.info("Connected!");
            }

            @Override
            public void onMessage(String s) {
                BytesTool.sendText(session, s);
            }

            @Override
            public void onClose(int i, String s, boolean b) {
                logger.info("Disconnected!");
            }

            @Override
            public void onError(Exception e) {

            }
        };
        webSocketClient.connect();
        sessionWebSocketClientMap.put(session, webSocketClient);
    }

    @OnMessage
    public void onMessage(String message, Session session) throws InterruptedException {<FILL_FUNCTION_BODY>}

    @OnClose
    public void onClose(Session session) {
        sessionWebSocketClientMap.get(session).close();
        sessionWebSocketClientMap.remove(session);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        logger.error(error.getMessage());
    }
}

        if (sessionWebSocketClientMap.get(session) != null) {
            try {
                sessionWebSocketClientMap.get(session).send(message);
            } catch (Exception e) {

            }
        }
    
<no_super_class>