private Handler<ServerWebSocket> webSocketHandler() {
    return websocket -> {
      final SocketAddress socketAddress = websocket.remoteAddress();
      final String connectionId = websocket.textHandlerID();
      final String token =
          AuthenticationUtils.getJwtTokenFromAuthorizationHeaderValue(
              websocket.headers().get("Authorization"));
      if (token != null) {
        LOG.atTrace()
            .setMessage("JWT authentication token {}")
            .addArgument(() -> truncToken(token))
            .log();
      }

      if (!hostIsInAllowlist(
          Optional.ofNullable(websocket.headers().get("Host")).orElse("NOHOST"))) {
        websocket.reject(403);
      }

      if (authenticationService.isPresent()) {
        authenticationService
            .get()
            .authenticate(
                token,
                user -> {
                  if (user.isEmpty()) {
                    websocket.reject(403);
                  } else {
                    final Handler<Buffer> socketHandler =
                        handlerForUser(socketAddress, websocket, user);
                    websocket.textMessageHandler(text -> socketHandler.handle(Buffer.buffer(text)));
                    websocket.binaryMessageHandler(socketHandler);
                  }
                });
      } else {
        final Handler<Buffer> socketHandler =
            handlerForUser(socketAddress, websocket, Optional.empty());
        websocket.textMessageHandler(text -> socketHandler.handle(Buffer.buffer(text)));
        websocket.binaryMessageHandler(socketHandler);
      }
      String addr = socketAddressAsString(socketAddress);
      LOG.debug("Websocket Connected ({})", addr);

      websocket.closeHandler(
          v -> {
            LOG.debug("Websocket Disconnected ({})", socketAddressAsString(socketAddress));
            vertx
                .eventBus()
                .publish(SubscriptionManager.EVENTBUS_REMOVE_SUBSCRIPTIONS_ADDRESS, connectionId);
          });

      websocket.exceptionHandler(
          t -> {
            LOG.debug(
                "Unrecoverable error on Websocket: {} ({})",
                t.getMessage(),
                socketAddressAsString(socketAddress));
            websocket.close();
          });
    };
  }
Construct a EngineJsonRpcService to handle either http or websocket clients

@param vertx The vertx process that will be running this service
@param dataDir The data directory where requests can be buffered
@param config Configuration for the rpc methods being loaded
@param metricsSystem The metrics service that activities should be reported to
@param natService The NAT environment manager.
@param methods The json rpc methods that should be enabled
@param maybeSockets websocket configuration to use
@param scheduler for managing ETH tasks
@param authenticationService used to grant or deny access to methods served
@param livenessService A service responsible for reporting whether this node is live
@param readinessService A service responsible for reporting whether this node has fully started
ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/EngineJsonRpcService.java