How do I get multiple services running on the same server to only use one external TCP port?

Hello,

Let’s assume I’ve got multiple RemObjects SDK services (as in separate executables, not RODL services) built as stand-alone Delphi VCL services (as in the Windows services concept) all running on the same Server. I’d like all services to be accessible through one single TCP Port on that Server: For my target audience configuring multiple routers and firewalls to allow access to multiple ports on the same system would be a deal-breaker. At the moment I’m using a simple client-server architecture where the SQL service runs on the Server and everyone connects to that single SQL service. This requires only one TCP port to be opened, and even that proves difficult at times. I guess a good name for what I’m trying to do is PROXY: I’d like to create a PROXY server that redirects all requests to services (as in other executable processes) that can actually handle the requests.

For analogy, if the Server was running a Web server (IIS or Apache), my multiple services would be CGI Servers, or Apache modules, or ISAPI modules installed in different directories of the server or accessed as name-based virtual servers. Externally they’d only use one port (most likely the HTTP port) so all firewalls and routers would only need to be configured to allow access to that one port. In this example the server opening the TCP port (IIS or Apache) knows practically nothing about what each individual service is going to do.

I’m hoping there’s a way to implement this as a RemObjects-SDK based solution so I’d get the opportunity to use other channels beyond HTTP: At a minimum I’d like to use both an IndyTCP-based channel and a HTTP-channel; The HTTP would be used if the IndyTCP can’t get through (for example from the Internet). The connection from this RemObjects SDK server to the real implementation would go over whatever channel is most efficient and easier to implement. For example a named-pipe channel: that would not interfere with AV software the client might have on that Server.

The solution I’ve attempted right now for the proxy server involves a fake class factory (something that implements IROClassFactory_ZeroConfig and says it can handle anything) and a IROInvoker that attempts dispatching the message to an other server, without trying to understand the message. So far it’s failing on the Real server when the real server tries to read the InterfaceName from whatever it receives. I’m going to hammer this a bit more as I think it might work, but I’m thinking of alternative implementations as well:

  • Maybe I should write a Channel implementation? This might allow me to use something HTTP or TCP based for the leg between the Client application and the Proxy server, then switch to something else (the mentioned Named Pipe) for the final leg to the Real server.

  • Maybe I should use a SOCKS proxy? I don’t particularly like this, but it can be done with off-the-component-palette components and it allows my multiple servers to be separate processes. First of all I don’t like this because it forces me to use a TCP-based channel for the connection to the Real server, can’t use Named Pipes.

  • Maybe I should give the HTTP Server based solution a bit more thought? It’d be very hard as my multiple services absolutely need to be separate processes. They can’t all load into the same process (as Apache modules would). And configuring multiple app domains in ISS doesn’t look like the kind of job my target audience would handle.

P.S: Here’s the code I’ve got in my proxy IROInvoker; I guess this is the most important piece of code in my attempted implementation:

function TFakeInvoker.HandleMessage(const aFactory: IROClassFactory; const aMessage: IROMessage; const aTransport: IROTransport; out oResponseOptions: TROResponseOptions): boolean;
var Ch: TROWinInetHTTPChannel;
begin
Ch := TROWinInetHTTPChannel.Create(nil);
try
Ch.TargetURL := ‘http://127.0.0.1:8098/bin’;
(Ch as IROTransportChannel).Dispatch(aMessage);
finally Ch.Free;
end;
end;

Thank you,
Cosmin Prund

Hi,

You can define several services in one RODL.

We’re running into a slight language problem since so may things go by the same name. We’ve got the “Services” in the RODL files, we’ve got the Services as in windows-services, and then I also called the executables, the processes themselves, services. All that because I can’t call them Servers as the machine itself is the Server, and I wanted to make the distinction between the Server itself and the Services that run on it.

I don’t want the Proxy process to implement all the RODL Services it might need to offer because I do not know those Services up-front. I also need my RODL Services to be implemented by different Windows processes (executables) for technical reasons.

The best name for the thing I want would be a “Proxy” - but I didn’t call I wanted to stay open to as many solutions as possible.

Sorry if I wasn’t clear enough. I’m going to edit the question again (while I still can) and qualify all those references to Services.

Thank you.

Hi.

Unfortunately RemObjects SDK doesn’t have a “transparent” proxy which can forward any message to another server(s). Need implement all RODL services in such proxy.

Yes these would be a realy nice thing.
A proxy that can be configured to forward to different instances of ro-services and da-services. I would like it… :wink:
Fritz

doesn’t IIS have a “proxy” module that can do this? Something like apache’s mod_rewrite/mod_proxy.

You are right i have to look at this,
Thanks fort the info sometimes its not easy to get all together :slight_smile:
Fritz

To me the most important issue is Deployment: It needs to be easy and it needs to be flexible. In fact that’s the only problem that the Proxy would solve, because if ease of deployment would not be taken into account, then I guess one could run as many ro-services instances as needed on a given server, each with it’s own ports and firewall rules.

Taking this into account, both IIS and Apache pose some deployment problems as they’re both huge bits of software designed to do allot more then just proxy-ing some HTTP connections. They’re really not the best tool for the job if one would be happy with simple HTTP proxy-ing: I’d rank a custom Indy based HTTP proxy allot higher since it’s not difficult to write and it’d be very easy to install and configure. The problem with any HTTP based solution is that it automatically assumes HTTP channels for all communications between RemObjects SDK services and clients.

A RO-SDK based solution would be very interesting, especially if it manages to use all of the Channel infrastructure already in place. One would be able to keep a uniform interface for the actual working RemObjects server instances (for example exclusively Named Pipes channels to further help with the deployment issue by NOT tripping any Anti-Virus software). It would allow the Proxy to support as many channels as required (again: TCP for high performance over the LAN, HTTP for easy access over the Internet, possibly even a Named Pipe channel). It would also be easy to adapt to situations where there’s already some HTTP Server software configured and in use on the server. For example I could have, on my deployment media, a stand-alone proxy service, a IIS module proxy service and a Apache module proxy service. And I’d install the one that is best fit, or possibly two (for example an IIS module if the user already has IIS and IIS got hold of port 80 and a stand-alone service so that my proxy-service can also handle TCP from the local LAN on a different port)

Hi,

unfortunately we don’t have plans implement such “transparent proxy”.