RTC Forums

Subscription => Support => Topic started by: HalcyonLogic on July 12, 2013, 05:54:16 PM



Title: Creating a proxy server (get from server)
Post by: HalcyonLogic on July 12, 2013, 05:54:16 PM
Let's assume the following scenario:
An RTC server is used as a web service type of application. Upon receiving a particular request from clients (browsers), the server should in turn make a request to a 3rd party web service and return a value received from it.

Basically, think of this as a proxy server in which MY server will call a DIFFERENTserver and return the response/value it got.

I am a little confuse on how to do this. How would I go about to do this? Would I use a TrtcDataProvider in which a TrtcDataRequest would be used to call the 3rd party service?

(Please forgive my ignorance).

Richard


Title: Re: Creating a proxy server (get from server)
Post by: D.Tkalcec (RTC) on July 12, 2013, 06:20:33 PM
Use the TRtcDataRouter component. That's one of the reasons it exists. It allows you to accept requests which are meant for a 3rd-party Server, check the request contents and modify it if needed, forward the request to the 3rd-party server, check the response if needed, and send it back to the Client/Browser from which the initial request arrived. Take a look at the "RTCLoadBalancer" Project in the Demos\LoadBalander folder for an example of using the TRtcDataRouter component.

Best Regards,
Danijel Tkalcec


Title: Re: Creating a proxy server (get from server)
Post by: HalcyonLogic on July 12, 2013, 06:23:14 PM
Thanks Danijel, I will have a look at it.


Title: Re: Creating a proxy server (get from server)
Post by: HalcyonLogic on July 12, 2013, 06:40:13 PM
Side note, I noticed the RTC Help files are all blank/emptied. Is there an updated help file somewhere?

Looking at demos helps but a help file would also be useful to figure out what component does what/should be used for and what each events are for (granted sometime it's obvious, but not always).



Title: Re: Creating a proxy server (get from server)
Post by: D.Tkalcec (RTC) on July 12, 2013, 07:23:07 PM
Help file is not blank not emptied. If you don't see the contents, it is because Windows has blocked it after the download. You need to right-click the CHM file, open file Proierties in Windows Explorer, then click "Allow" and confirm it. After you close the properties dialog, you should see the full contents of the Help.CHM file.

TRtcDataRouter and TRtcLoadBalancer components are fully documented in the HELP file (all properties, methods and evnents), and the Demo project I've pointed out include detailed explanations of all implemented events.

Best Regards
Danijel Tkalcec


Title: Re: Creating a proxy server (get from server)
Post by: HalcyonLogic on July 12, 2013, 07:40:19 PM
Sorry, my bad.

Got to love when Windows blocks stuff for you.


Title: Re: Creating a proxy server (get from server)
Post by: HalcyonLogic on July 12, 2013, 09:04:41 PM
I'm sorry but I am going to need a little more info. After looking at the demos, I am more confused then ever.

Could you please describe at a higher level overview how all those pieces should be connected/work with one another?

Why would I need a TRtcCritSec or TXObjList? Not sure I get what they do?
Help says: TRtcCritSec: This is the object class which has to be extended with your object information if you want to pass objects to RTC components. Say what!??

Please explain the OLDRequest vs NEWRequest thing?

Seems to me that all the pieces I would need are:
An OnCheckRequestI event-> Would be used to catch the original request, accept it, then modify it so we can call the 3rd party web service from which I need a response.
An OnPostNewRequestI event -> Would be used to actually POST my modified request to the 3rd party web service from which I need a response.
Not sure how to catch the response from 3rd party web service, so I can read, analyse and return it to my original request.





Title: Re: Creating a proxy server (get from server)
Post by: HalcyonLogic on July 12, 2013, 09:11:36 PM
A bit more info on what I am trying to archive:

I need to have a way for my server to be able to accept a request from my web clients (browsers), modify the header, call a 3rd party web service, get a response/value back and return it to my caller.

Ex:
  • My server get a /GetXYZValueFrom3RDParty request
  • Server calls www.3rdparty.com/GetValue?ID=1
  • Because some processing may be needed, server keeps polling/waiting for a response until 3rd party web service is ready
  • 3rd party web service sends back response
  • Server reads response and finally returns value to original caller


Title: Re: Creating a proxy server (get from server)
Post by: D.Tkalcec (RTC) on July 12, 2013, 09:25:58 PM
Sorry, I've pointed you at the wrong Project. Please, take a look at "RTCRouter" and "RTCRouter2" Projects from Demos. They are a lot simpler than the Load Balancer Project and contain a more detailed explanation of what you need (routing of requests). All events you need to implement what you want, are on the TRtcDataRouter component.

TRtcCritSec is a critical section object (=TCriticalSection in Delphi), TXObjList is an object list. Both of these are used for managing a pool of TRtcDataRequest and TRtcHttpClient components, so they can be re-used. If you don't know which Server your request will end up on, and it is more likely that it will always be a different Server, then you can also create TRtcHttpClient and TRtcDataRequest components when needed and destroy them immediately afterwards (see TRtcDataRouter event descriptions).

NOTE: There is no "pooling", because the request will be sent asynchronously and you will get events on the TRtcDataRouter component when data arrives, just like you would when using TRtcDAtaRequest components. The difference in using TRtcDataRequest and TRtcHttpCLient component directly, is that using the TRtcDataRouter component handles the data flow between your incoming connection to your Server and the outgoing connection to the 3rd-party Server for you. You just need to "tell" the components what you want. And this is done by implementing events of the TRtcDataRouter component.

Best Regards,
Danijel Tkalcec


Title: Re: Creating a proxy server (get from server)
Post by: HalcyonLogic on July 12, 2013, 09:41:34 PM
But my questions remains though (please see my 2 previous posts).

Could you please describe at a higher level overview how all those pieces should be connected/work with one another?
Why would I need a TRtcCritSec or TXObjList? Not sure I get what they do?
Help says: TRtcCritSec: This is the object class which has to be extended with your object information if you want to pass objects to RTC components. Say what!??
Please explain the OLDRequest vs NEWRequest thing?



Title: Re: Creating a proxy server (get from server)
Post by: D.Tkalcec (RTC) on July 12, 2013, 09:43:58 PM
Please, read my reply again. I was editing it while you were typing.


Title: Re: Creating a proxy server (get from server)
Post by: HalcyonLogic on July 12, 2013, 10:07:34 PM
Please explain the OLDRequest vs NEWRequest thing?

An OnCheckRequestI event-> Would be used to catch the original request, accept it, then modify it so we can call the 3rd party web service from which I need a response.
An OnPostNewRequestI event -> Would be used to actually POST my modified request to the 3rd party web service from which I need a response.
Not sure how to catch the response from 3rd party web service, so I can read, analyse and return it to my original request.

How do I catch the response from 3rd party web service?


Title: Re: Creating a proxy server (get from server)
Post by: D.Tkalcec (RTC) on July 12, 2013, 10:18:36 PM
TRtcDataRouter component has a lot of events, because it can be used for implementing everything from a simple data router, forwarding all incoming requests to a sepecific Address and routing the response back to the Client, through Proxy Servers which need to forward requests to different Servers and can use a pool of connections for each Server, or a load balancer which should balance the Load between multiple Servers responsible for processing requests from a single Application.

The minimum events you should implement on the TRtcDataRouter component are:

* OnCheckRequestI - to accept requests which you want to process/forward and mark the request for buffering, if you want to modify the request content body before it is sent to the 3rd-party Server.

* OnPostNewRequest - here, you should create a TRtcHttpClient component and and TRtcDataRequest component, link them together and set all their properties needed for opening a connection to the 3rd-Party Server (like ServerAddr and ServerPort). You will get the Sender parameter here as well, from where you can access the Request object.

* OnPostReturn - will be called after the TRtcDataRequest component (linked to a TRtcHttpClient) is no longer needed. You can destroy both components here if you are not using a component pool.

All the other events are used for handling incoming and outgoing requests and responses, so you should read what which event does and decide which one(s) you need to implement for your specific requirements.

Receiving Request from the Client ...
* OnRequestReceivedI
* OnRequestReceiveAbortI

Forwarding Request to the 3rdParty Server ...
* OnRequestBeginO
* OnRequestSentO
* OnRequestSendAbortO

Receiving Response from the 3rdParty Server ...
* OnResponseBeginO
* OnResponseReceivedO
* OnResponseReceiveAbortO

Forwarding Response to the Client/Browser ...
* OnResponseSentI
* OnResponseSendAbortI

You can find detailed explanations of all these events in the HELP file and in RTCRouter* Demo Projects.

Best Regards,
Danijel Tkalcec


Title: Re: Creating a proxy server (get from server)
Post by: HalcyonLogic on July 12, 2013, 10:25:24 PM
How is using the ReqClosing:boolean; variable in the demos public definition sections make this thread safe?







Title: Re: Creating a proxy server (get from server)
Post by: D.Tkalcec (RTC) on July 12, 2013, 10:39:01 PM
In this case, using a global boolean is thread-safe. If the variable was part of an object which could be destroyed while the code accessing that variable was still running, or if the variable was used inside a loop and the compiler would optimize it to move the variable into a register, then using a boolean - or any other type of a global variable- would NOT be thread-safe.

PS. We are talking about a single boolean variable, not about an object, pointer or String. Accessing objects, pointers, Strings, arrays or any other structure whose location or organization in memory could change on use is NOT thread-safe, unless done inside a critical section to ensure that only one thread will have access to it at a time.

Best Regards,
Danijel Tkalcec


Title: Re: Creating a proxy server (get from server)
Post by: D.Tkalcec (RTC) on July 12, 2013, 10:45:31 PM
As a side note ... ReqClosing is a variable which whould normally only be set to TRUE when the Application is terminating. It is a singnal that all request processing should stop. That variable would not change its state before the Application is ready to terminate.

Best Regards,
Danijel Tkalcec


Title: Re: Creating a proxy server (get from server)
Post by: HalcyonLogic on July 12, 2013, 11:57:42 PM
Ok, I've been starring at the demos for 7 hours now. Can't help thinking that there must be an easier way to do what I am trying to do.

What I am trying to archive is what this PHP code does:
$my_result = file_get_contents('https://www.3rdparty.com.test.net/someweblibarry.dll?Prop1=value1&Prope2=value2');
parse_str($my_result, $arr);
$result['TEST'] = $arr['TEST'];

Am i crazy or your demo requires a lot of of code to replace these 3 lines?

I found a work around here: http://stackoverflow.com/questions/301546/whats-the-simplest-way-to-call-http-get-url-using-delphi
This simple routine allows me to make a call to the webservice in question (using WinInet) and get it's response (without having to do all the work/events described in your demo).

Richard



Title: Re: Creating a proxy server (get from server)
Post by: HalcyonLogic on July 13, 2013, 12:38:58 AM
The WinInet work around does the rick for me, however, I would have liked to stick to RTC stuff.

Someone suggested to me using some of the Indy nightmare crap (I am not a big fan of Indy, never been, I try to avoid it like the plague if I can).

By all means, if my original question was misunderstood and RTC has a more elequent way of doing this, I am all ears.

Richard


Title: Re: Creating a proxy server (get from server)
Post by: D.Tkalcec (RTC) on July 13, 2013, 06:51:00 AM
With a TRtcDataRouter component, you have two advantages:

1) There are no threads blocking while waiting for a response from the Server.

2) If you don't need to modify the content body of the Response received from the 3rd-party Server, there is no need to buffer the complete response on your Server before it goes out to the Client, which has the advantage that your Clients will receive the response sooner, and your Server will only use a few KB of RAM to handle responses of any size (no intermediate buffering).

But ... if your Server only needs to handle a few Clients sending requests, and the size of each Response received from the 3rd-party Server is guaranteed to be small, the implementations you have found will also do the trick.

Best Regards,
Danijel Tkalcec