TL;DR: you might not even need nginx, fly-replay
will likely do what you want.
This may turn out to be way simpler than you think. I have an application where requests have affinity - the details are quite different, but the result is the same. But first, let me back up.
Request come into the fly network and are handled by one of our edge servers. We have no control over where the come in. We route those requests to the nearest server that you have deployed your application. The result is both more random and more complicated than this, but this is the effective result.
Now to answer your first question, no you can’t currently customize the default fly.io load balancer to do what you describe. This is on the todo list, but I have no insight as to when that might be available and if the final result will meet your needs.
So now, a request comes in and it might be to the wrong server. All you need to do is to respond back with a fly-replay
and our proxy will then forward it to the right place. This could be another application, another instance of the same application in a different region, or even a specific machine.
If this works for you… you are done! You haven’t mentioned what language and framework you are using but many frameworks allow you to define middleware that is run on every request. Have it check for a session/cookie/whatever and respond with a fly-replay
header if the request needs to be handled elsewhere. In my case, I’m already running nginx on every machine, so I handle this there.
The only caution is that this is limited to requests that have a payload of less than a megabyte. In your case, it looks like you are only looking to set up a socket so this is not likely a concern - the size of the data sent across the socket once established is not an issue, it is only the original HTTP request that matters. In my application, I successfully replay requests to set up websockets all the time.
My application does have a need to handle uploading of files that may be larger than one megabyte, and I handle that by doing a reverse proxy in nginx, and routing it using the .internal
address. This also works.