For clarity - I’ll refer to CasparCG as being local and your webserver as being Remote.
Close - you’d have the local node app running on CasparCG box open a socket connection to your remote webserver - exactly like it is a client. That local proxy app also opens a TCP connection to CasparCG localhost and pipes everything between the TCP & WS. I’m sure you’ll find loads of examples on github to get started.
On the webserver, remote, side it’s up to you how you integrate with Caspar-Control and plumb the websocket - either cutting out caspar-control’s TCP socket & using the websocket native. Or by implementing the same proxy idea on the server where Caspar-Control opens its usual TCP connection but instead of to a CasparCG instance it’s to a TCP socket block running within your webserver’s node app & pipe WS & TCP together just as you did on the client.
Caveats: Be sure to only allow localhost connections on your TCP sockets on either end. On the server your websocket should only accept a connection with an auth token from the client - just throw a hashed secret in a header & check for it on the server.
Bonus: Once you’ve set up the TCP over WS proxy it would be trivial to add in OSC proxying.
This is all a bit cludgey & all things that a quick SSH tunnel or even a VPN would fix - but we’re staying out of networking land.
Still a neat little trick to add to your repertoire of hackery though. It has loads of uses.