Products

Price/Order

Support

Partners

Testimonials

Test Results

About us

Contact
 How to convert project to ISAPI Extension
Bottom
 
Total posts: 11
 Author How to convert project to ISAPI Extension
Christopher Fieldhouse

20.06.2006 22:59:34
Registered user
Hi

Quote...
"In case you want to keep using your existing Web Server (like Apache or MS IIS), but would also like your new RTC applications to run on port 80, you also have the option to compile your Server-side code as one (or more, if you want) ISAPI extension, so it can be installed and used from within your other Web Server and run parallel to your existing Web Applications."

Is there an easy way to do this, by changing a project option etc?

Thanks

Chris
Danijel Tkalcec [RTC]

21.06.2006 02:41:59
Registered user
Generaly, it's an easy task if you have your code prepared for this, even though ISAPI extensions are DLL files, while stand-alone Servers are executables.

To get your code running as an ISAPI extension, you will need to create a new project by using the rtcISAPIProject "template project" from the Lib folder. For a step-by-step guide on creating a new ISAPI Project, please see the Quick-Start guide (Server Lesson 6: Write an ISAPI Extension using RTC).

Once you have the ISAPI Project ready (you only need the ISAPI Project with one DataModule and a rtcISAPIServer component), you can already compile it into an ISAPI Extension. But, it won't do much, since there is no application code associated with the component.

If you have all your application code separated inside a TDataModule (using TRtcDataServerLink instead of the TRtcHttpServer component), you can skip the next 3 paragraphs, since they explain how to create that TDataModule if you have put all your code in a visual Form ...

---
If you have your Stand-alone Server components and code inside a (visual) Form, probably with a TRtcHttpServer component on it, the first thing you will need to do is to create a new TDataModule (non-visual components container - comparable to a form), add a TRtcDataServerLink component to the TDataModule, give that TRtcDataServerLink the same name you gave your rtcHttpServer component on the Form, then copy all your non-visual RTC components (TRtcDataProvider, TRtcServerModule, TRtcFunctionGroup and TRtcFunction) with all their application code (events) to that new TDataModule, except the TRtcHttpServer component (this is a pure connection component and should have no application-specific code).

After you copy everything but your TRtcHttpServer component to that new TDataModule, make sure that all the components are linked to the TRtcDataServerLink component, the same way they were linked to the TRtcHttpServer component on the (old) Form.

After you've done that, you will have a RTC Server plug-in component (TDataModule), which you can link to any TRtcHttpServer and/or TRtcISAPIServer component, in any project.
---

To give the ISAPI extension something to do, link the TRtcDataServerLink component from your "application code TDataModule" to your rtcISAPIServer component, at runtime. You can do that from the OnCreate event in your ISAPI Project's DataModule, on which you have placed your rtcISAPIServer component.

You can add any intialization code for your application to rtcISAPIServer's OnStartListen event, or to the OnCreate event of the main ISAPI DataModule. And ... that's it. You have your ISAPI Extension completed.

The same way, you can link the TRtcDataServerLink component from your "application code TDataModule" to a rtcHttpServer component in a stand-alone Server project - at runtime.

For 3 examples on re-using application code to compile 3 different projects, take a look at projects in the Demos/RTC_WebForum folder. All three projects use the same Web Forum application code, but compiled for different targets:
- RTCWebForum = Stand-alone Server using HTTP
- RTCWebForumTLS = Stand-alone Server using HTTPS (SSL)
- WebForum_ISAPI = ISAPI Extension

You will see that all three projects use the same application code, which is kept in a DataModule, but the Server connection components (rtcHttpServer or rtcISAPIServer) are on a separate DataModule.

If you want to avoid doing all of that in the first place, it's best to always place your application code in a TDataModule and use a separate TDataModule for the Server connection component. That way, you can always reuse your code and integrate it into any other RTC Server project.

For example, even if you only need a stand-alone server, you may want your application to run either as a normal Windows application in a Window, or as a Windows Service. Keeping your application code separeted from your connection components will make it easy to compile the same application into a "Visual Server" and into a non-visual Windows Service.

Please note that internaly, there is a big difference between ISAPI extensions and stand-alone servers. It's a completely different infrastructure at work. But, RTC SDK hides this as much as possible by using one set of components for writing the application code and ... by providing almost identical interface for ISAPI and Stand-alone applications (TRtcDataServer class).

Best Regards,
Danijel Tkalcec
Christopher Fieldhouse

21.06.2006 18:34:35
Registered user
Hi Danijel

Thanks for the reply but I'm afraid I'm stuck as I cannot get it to work.  When you get a moment could you describe the exact steps required to convert lesson 3 (create remote functions) to an ISAPI dll please.

Much appreciated

Chris
Christopher Fieldhouse

21.06.2006 19:00:09
Registered user
I've just been playing with the AppServer & AppClient demos in the SDK.  The app server demo compiles and works great, the AppServerISAPI project compiles but the client cannot seem to connect when I use the downloadable RTCWebserver as the webserver.

Could you have a look at this as clearly I am doing something wrong.

Thanks

Chris
Danijel Tkalcec [RTC]

21.06.2006 20:13:31
Registered user
When a client talks to an ISAPI extension, it has to add ISAPI's path to it's rtcClientModule's ModuleFileName property, since ISAPI extensions are running in "virtual folders" on the Web Server.

For example, if you have a rtcServerModule and set ModuleFileName="/functions", if that rtcServerModule is running in a stand-alone server, your rtcClientModule will only need to set ModuleFileName="/functions" to access remote functions.

But, when that same rtcServerModule is running inside an ISAPI Extension, since that ISAPI extension is running inside a "virtual folder" in the Web Server, your Client will need to add the ISAPI path to rtcClientModule's ModuleFileName property to access the functions.

In other words, if you set up the ISAPI extension to run as "/myisapi.dll" and your rtcServerModule has ModuleFileName="/functions", your rtcClientModule has to set it's ModuleFileName to "/myisapi.dll/functions" to access remote functions provided by that rtcServerModule running in that ISAPI extension.

The ModuleFileName property of rtcServerModule is nothing more than the Request.FileName (URI) which your component is using to accept and process incoming requests.

When your rtcServerModule is moved to an ISAPI extension, RTC takes care of "removing" the virtual folder part from Request.FileName, so that the same code works inside an ISAPI as it does inside a stand-alone server. But, clients accessing that ISAPI have to use the complete URI.

As a comparison, if you created an ISAPI extension which would serve HTML pages (regardless of which components or tools you use for that), then set that ISAPI extension up to run in a virtual folder "/mypages/" on your Web Server, any Browser trying to access the files from your ISAPI extension will need to include the location ("/mypages/") in the URL. If those pages would be running in a root folder of a stand-alone server, there would be no need to include the path.

I hope that explains the need to include ISAPI's path in ModuleFileName on the Client. Please let me know if you are unable to access remote functions running inside the ISAPI, even when you add your ISAPI's Path to your rtcClientModule's ModuleFileName.

Best Regards,
Danijel Tkalcec
Christopher Fieldhouse

21.06.2006 21:08:53
Registered user
Hi Danijel

Thanks for the explanation, that made all the difference.

I've managed to get it working as an ISAPI extension on my webserver running against the RTC Webserver (it is a lot slower than the remote function that is compiled directly into the server though).

The next hurdle is to try and get the ISAPI.dll running under Apache, are all the settings on the client exactly the same or is there something to change etc?

Thanks

Chris
Danijel Tkalcec [RTC]

21.06.2006 22:04:37
Registered user
Client settings only differ in the ModuleFileName property (the URL where the ISAPI is running). There is nothing else to it. When you install the ISAPI on Apache, you will only need to modify the rtcClientModule.ModuleFileName to point to the "virtual folder" of your ISAPI extension.

There is a FAQ for setting up an ISAPI in Apache.
Please note that you need Apache version 2.0 or later.

As for the speed difference, it all depends on the code that needs to be executed vs. communication overhead between the Server application and the DLL. One reason for a slow-down could be the fact that all data has to be shuffled back-and-forth between the DLL and the EXE, by using the "IS API".

Best Regards,
Danijel Tkalcec
Christopher Fieldhouse

21.06.2006 22:38:41
Registered user
I'm so close I can smell it!

I followed the FAQ exactly and created the file structure as described, I placed my DLL in the MyISAPI folder and restated Apache(2.0.55) at which time I got an error stating that "AllowOverride None" is "not allowed here"?  I commented that out and restarted again.

I have changed the ModuleFileName to "/myisapi/OnyxRTCAddressServerISAPI.dll/test" and tested again, and it doesn;t work now (ARGHHHHH....)

I have followed the events and I get "RtcHttpClient1Connecting", RtcHttpClient1Connect, RtcHttpClient1DataOut, RtcHttpClient1DataIn but now I don't get RtcResult1Return.

Do you have any ideas?

Thanks

Chris F
Danijel Tkalcec [RTC]

21.06.2006 22:50:26
Registered user
I hope you haven't changed ModuleFileName in your rtcServerModule (ISAPI extension), but only on rtcClientModule (Client app).

The events only say that you could connect to the server, send something out and get something back. You will get those events even if you don't set up the ISAPI. You are connecting to the Server, not the ISAPI.

If you are using the same ISAPI which works in the RTC WebServer, but your client can't access it, your ISAPI is not set up correctly. Any ISAPI that works on a RTC WebServer, will work on Apache 2.x also, it just needs to be set up correctly. You may need to check Apache documentation to see why it doesn't accept the "AllowOverride" option for your ISAPI extension.

Best Regards,
Danijel Tkalcec
Christopher Fieldhouse

21.06.2006 22:57:38
Registered user
Yahoo, it works.

I changed the entry in the Apache file to

ScriptAlias /myisapi/ "C:/RTC/MyISAPI/"

<Directory "C:/RTC/MyISAPI">
AddHandler isapi-isa .dll    
AllowOverride None
    Options ExecCGI
    Order allow,deny
    Allow from all
</Directory>

And it all just works.

And now my daughter isn't playing Sims2 on the webserver the speed is back to the same as when compiled directly into the RTCServer, starting the DLL requires more CPU grunt than exsecuting an already running process.

Thank you so much for your help, all this web stuff is totally new to me.  I wouldn't have enven tried without your components so once again, thank you for all the help and support (which I've got to say is just about real time (even at 9.45 PM as it is here in the UK)).

Hope you have a good evening,

Chris

Oh, just thought of a question, should I have turned on MultiThreaded in the TRtcISAPIServer?
Danijel Tkalcec [RTC]

21.06.2006 23:06:59
Registered user
Thank you for posting correct settings for the new Apache Server.
I will update the FAQ with this info now.

About the speed difference ...

I would have expected some minor performance penalty with very short remote calls when data is shuffled back-and-forth between the Server and the ISAPI dll, but I was also a bit surprised when you said it was a lot slower (gulp). I'm glad there isn't a noticable slow-down when running the code from inside the ISAPI extension.

There is a way to force Apache to keep some ISAPI extensions loaded all the time, which will reduce the chance of Apache unloading and loading the ISAPI too often. I think it's done by adding the "ISAPICacheFile" option for the DLL file, like this:
ISAPICacheFile C:/RTC/MyISAPI/mytest.dll

About your question ...

Properties on the rtcISAPIServer component are ignored, only events are used. ISAPI extensions run in the thread context created by the Web Server now. I've left those properties visible, in case I should change the ISAPI implementation to use the thread-pooling mechanisms used by the stand-alone RTC Server.

Best Regards,
Danijel Tkalcec