docs: protected ChannelFuture handleHandshake(ChannelHandlerContext ctx, NettyHttpRequest req, WebSocketBean<?> webSocketBean, MutableHttpResponse<?> response) {
          int maxFramePayloadLength = webSocketBean.messageMethod().flatMap(m -> m.getValue(OnMessage.class, "maxPayloadLength", Integer.class)).orElse(65536);
          WebSocketServerHandshakerFactory wsFactory =
                  new WebSocketServerHandshakerFactory(
                          getWebSocketURL(ctx, req),
                          null,
                          true,
                          maxFramePayloadLength
                  );
          handshaker = wsFactory.newHandshaker(req.getNativeRequest());
          MutableHttpHeaders headers = response.getHeaders();
          io.netty.handler.codec.http.HttpHeaders nettyHeaders;
          if (headers instanceof NettyHttpHeaders) {
              nettyHeaders = ((NettyHttpHeaders) headers).getNettyHeaders();
          } else {
              nettyHeaders = new DefaultHttpHeaders();
              for (Map.Entry<String, List<String>> entry : headers) {
                  nettyHeaders.add(entry.getKey(), entry.getValue());
              }
          }
          Channel channel = ctx.channel();
          if (handshaker == null) {
              return WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(channel);
          } else {
              return handshaker.handshake(
                      channel,
                      req.getNativeRequest(),
                      nettyHeaders,
                      channel.newPromise()
              );
          }
      }