Port knocking appeals to me because of how few bytes you have to send. But a system I’ve been thinking of (and surely a bunch of people before me) goes like this:
Instead of knocking on ports, send actual HTTP requests to different paths. Over TLS or just plain HTTP.
So where you’d port knock a sequence of ports here instead you send GET requests to some different, publicly known paths
GET /index.htm
GET /about_us.htm
GET /about_us.htm
GET /index.htm
GET /about_us.htm
GET /products.htm
You get the idea.
And now then the challenge is that if you’re on a network that does HTTP caching, it would interfere with this.
But we already have the well known cache-busting technique for that right, so
GET /css/main.css?ver=64729929
GET /js/bundle.js?ver=947367292
GET /js/bundle.js?ver=7483939
And so on. And version is for example current Unix time and is actually ignored in terms of “knocking”. Only the path matters.