public static void echoFrame ( final WebSocketChannel channel , final StreamSourceFrameChannel ws ) throws IOException { final WebSocketFrameType type ; switch ( ws . getType ( ) ) { case PONG : // pong frames must be discarded ws . close ( ) ; return ; case PING : // if a ping is send the autobahn testsuite expects a PONG when echo back type = WebSocketFrameType . PONG ; break ; default : type = ws . getType ( ) ; break ; } final StreamSinkFrameChannel sink = channel . send ( type ) ; sink . setRsv ( ws . getRsv ( ) ) ; initiateTransfer ( ws , sink , new ChannelListener < StreamSourceFrameChannel > ( ) { @ Override public void handleEvent ( StreamSourceFrameChannel streamSourceFrameChannel ) { IoUtils . safeClose ( streamSourceFrameChannel ) ; } } , new ChannelListener < StreamSinkFrameChannel > ( ) { @ Override public void handleEvent ( StreamSinkFrameChannel streamSinkFrameChannel ) { try { streamSinkFrameChannel . shutdownWrites ( ) ; } catch ( IOException e ) { UndertowLogger . REQUEST_IO_LOGGER . ioException ( e ) ; IoUtils . safeClose ( streamSinkFrameChannel , channel ) ; return ; } try { if ( ! streamSinkFrameChannel . flush ( ) ) { streamSinkFrameChannel . getWriteSetter ( ) . set ( ChannelListeners . flushingChannelListener ( new ChannelListener < StreamSinkFrameChannel > ( ) { @ Override public void handleEvent ( StreamSinkFrameChannel streamSinkFrameChannel ) { streamSinkFrameChannel . getWriteSetter ( ) . set ( null ) ; IoUtils . safeClose ( streamSinkFrameChannel ) ; if ( type == WebSocketFrameType . CLOSE ) { IoUtils . safeClose ( channel ) ; } } } , new ChannelExceptionHandler < StreamSinkFrameChannel > ( ) { @ Override public void handleException ( StreamSinkFrameChannel streamSinkFrameChannel , IOException e ) { UndertowLogger . REQUEST_IO_LOGGER . ioException ( e ) ; IoUtils . safeClose ( streamSinkFrameChannel , channel ) ; } } ) ) ; streamSinkFrameChannel . resumeWrites ( ) ; } else { if ( type == WebSocketFrameType . CLOSE ) { IoUtils . safeClose ( channel ) ; } streamSinkFrameChannel . getWriteSetter ( ) . set ( null ) ; IoUtils . safeClose ( streamSinkFrameChannel ) ; } } catch ( IOException e ) { UndertowLogger . REQUEST_IO_LOGGER . ioException ( e ) ; IoUtils . safeClose ( streamSinkFrameChannel , channel ) ; } } } , new ChannelExceptionHandler < StreamSourceFrameChannel > ( ) { @ Override public void handleException ( StreamSourceFrameChannel streamSourceFrameChannel , IOException e ) { UndertowLogger . REQUEST_IO_LOGGER . ioException ( e ) ; IoUtils . safeClose ( streamSourceFrameChannel , channel ) ; } } , new ChannelExceptionHandler < StreamSinkFrameChannel > ( ) { @ Override public void handleException ( StreamSinkFrameChannel streamSinkFrameChannel , IOException e ) { UndertowLogger . REQUEST_IO_LOGGER . ioException ( e ) ; IoUtils . safeClose ( streamSinkFrameChannel , channel ) ; } } , channel . getBufferPool ( ) ) ; }
Echo back the frame to the sender