RTC Forums
November 25, 2024, 05:59:13 AM *
Welcome, Guest. Please login or register.

Login with username, password and session length
 
   Home   Help Login Register  
Pages: [1]
  Print  
Author Topic: Using XML-RPC with Rtc Remote Functions...  (Read 10169 times)
Shane@StumpWare.com
Guest
« on: December 07, 2009, 10:27:53 PM »

I am attempting to extend a middleware framework I have been working on to not only support RTC clients, but clients who are capable of using XML-RPC.

I have set the DataFormats property on my TRtcServerModule to support all formats.

When I try and call a simple function I have written called Add2Numbers with the WebInject (http://www.webinject.org/webservices.html), I keep getting an

OnRequestNotAccepted event on my TRtcHttpServer. The error message is that POST is not supported function.

I am using the following scripts in WebInject:

TestCases.xml

<testcases repeat="1">

<case
    id="1"
    description1="Web Services Sample - Add2Numbers"
    url="http://127.0.0.1"
    method="post"
    posttype="text/xml"
    postbody="file=>Add2Numbers.xml"
    verifypositive="5"
   
/>

Add2Numbers.xml

<?xml version="1.0"?>
<methodCall>
  <methodName>Add2Numbers</methodName>
  <params>
    <param>
        <value><i4>2</i4></value>
    </param>
    <param>
        <value><i4>3</i4></value>
    </param>
  </params>
</methodCall>

What am I doing wrong?

Best Regards,

Shane


</testcases>
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #1 on: December 07, 2009, 10:51:11 PM »

OnRequestNotAccepted means that none of the rtcDataProvider or rtcServerModule components are set up to handle the request.

What is most likely happing in your case is that your "ModuleFileName" property on your rtcServerModule component does not match the URI requested by your test Client, so the request ends up "not accepted" instead of being processed by your rtcServerModule component.

In other words, if you set rtcServerModule's ModuleFileName property to "/myfuncs" then you also need to send your remote function call to the "/myfuncs" URI in order to have it processed. If I understand the test framework you are using, then your problem is most likely in the url parameter inside your TestCases.xml file. As I see it, the url parameter is currently "http://127.0.0.1" but should be "http://127.0.0.1/myfuncs" (replace "/myfuncs" with the value you have set for ModuleFileName on the rtcServerModule component).

When you do that, you will get the request sent to the right component. Then you only need to link a TRtcFunctionGroup to your rtcServerModule and link a TRtcFunction component with FunctionName "Add2Numbers" to get your TRtcFunction components OnExecute event called, where your request will arrive in form of an array called "params" with 2 integer parameters.

Best Regards,
Danijel Tkalcec
Logged
Shane@StumpWare.com
Guest
« Reply #2 on: December 07, 2009, 11:01:22 PM »

Danjiel,

Thanks - that was the trick!

Now I have to decide if I need / want to have sessions (manually since not necessarily using Rtc client)...!!!

Merry Christmas & Happy New Year!

Shane
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #3 on: December 07, 2009, 11:14:09 PM »

Glad to be of help.

Please note that the RTC SDK has its own specific way for sending and receiving session IDs, which you will need to know if you want to implement a client using the same Session mechanisms as the RTC SDK but use third-party technology for it. Should you need more detailed information on this topic, please let me know.

PS. Merry Christmas & Happy New Year Smiley

Best Regards,
Danijel Tkalcec
Logged
Shane@StumpWare.com
Guest
« Reply #4 on: December 07, 2009, 11:27:06 PM »

Well, the good news is that MY FUNCTION is getting called!

The BAD news is that the parameters aren't getting passed! The XML-RPC below

<?xml version="1.0"?>
<methodCall>
  <methodName>Add2Numbers</methodName>
  <params>
    <param>
        <value><i4>2</i4></value>
    </param>
    <param>
        <value><i4>3</i4></value>
    </param>
  </params>
</methodCall>

When it gets to my Add2Numbers() function, the Param->Count() shows only 1 value and it is 0.

I will check the data types to see if i4 isn't supported, but any ideas on what I am doing WRONG now  Huh!

Merry Christmas & Happy New Year!

Shane

P.S. And yes to the explanation on how to handle sessions! I was thinking about having OpenSession() / CloseSession() functions and making the user pass in the session id as part of the other other functions!
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #5 on: December 07, 2009, 11:40:21 PM »

<i4> is a supported data type and the XML you have posted should be correctly parsed by the RTC SDK. Can you check what you get if you use "Param.toXMLRPC" from the "Add2Numbers" OnExecute event please?

Best Regards,
Danijel Tkalcec
Logged
Shane@StumpWare.com
Guest
« Reply #6 on: December 07, 2009, 11:48:59 PM »

The Param->toXMLrpc() returns the string below:

<methodCall><methodName>Add2Numbers</methodName><params>
<param><value><i4>2</i4></value></param>
<param><value><i4>3</i4></value></param>
</params></methodCall>

It looks good to me!

Edit: Well, I figured it out ... I was expecting each parameter to be individual and not as an array! I guess I need to pass my values as a structure so I have names on the parameters!



Merry Christmas & Happy New Year!

Shane
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #7 on: December 08, 2009, 12:03:55 AM »

In your XML-RPC example ...

Param.Count should return 1
Param.FieldName[0] should return 'PARAMS' (your <params> structure)

Param.isType['PARAMS'] should return rtc_Array
Param.asArray['PARAMS'].Count should return 2 (your 2 <param> items)

Param.asArray['PARAMS'].isType[0] should return rtc_LargeInt (your 1st <param>)
Param.asArray['PARAMS'].asLargeInt[0] should return 2

Param.asArray['PARAMS'].isType[1] should return rtc_LargeInt (your 2nd <param>)
Param.asArray['PARAMS'].asLargeInt[1] should return 3

In other words, the correct way to send out your result as a sum of 1st and 2nd value in C++ would probably be ...

Result->asLargeInt = Param->asArray["PARAMS"]->asLargeInt[0] + Param->asArray["PARAMS"]->asLargeInt[1];

Please let me know if you have any other questions or encounter any irregularities.

Best Regards,
Danijel Tkalcec
Logged
Shane@StumpWare.com
Guest
« Reply #8 on: December 08, 2009, 12:09:04 AM »

It looks like we were answering at the same time!

I am going to pass my data in structures so I can access the values via name!

BTW, is my id about using remote functions for OpenSession() / CloseSession() the way to go and just have the user pass the session id into all the other functions?

Merry Christmas & Happy New Year!

Shane
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #9 on: December 08, 2009, 12:19:04 AM »

Yes, it would be best if yo would send your function parameters inside a single structure so you can use names for your parameters instead of working with an array of unnamed parameters. By passing a single <struct> inside your XML-RPC request, the RTC SDK will understand this as calling a function with named parameters and give you access to each parameter directly from the Param record, without going through the "PARAMS" array.

In other words, if you send an XML-RPC request like ...

<?xml version="1.0"?>
<methodCall>
  <methodName>Add2Numbers</methodName>
  <params>
    <param>
        <struct>
          <member>
              <name>par1</name>
              <value><i4>2</i4></value>
          </member>
          <member>
             <name>par2</name>
             <value><i4>3</i4></value>
          </member>
       </struct>
    </param>
  </params>
</methodCall>

... then you will have access to your 2 parameters through Param.asLargeInt['par1'] and Param.asLargeInt['par2'] directly (Param->asLargeInt["par1"] and Param->asLargeInt["par2"] in C++), so ... in order to return a result as a sum of these 2 values, you could use something like ...

Result->asLargeInt = Param->asLargeInt["par1"] + Param->asLargeInt["par2"];

BTW ... to pass Session IDs between your custom client and your RTC Server, I would recommend using the same way RTC SDK does it. And that is by using the "ID" query parameter as part of the URI sent from the Client to pass the SessionID to the Server, and using the "ID" cookie on the Client side to receive the SessionID from the Server.

Best Regards,
Danijel Tkalcec
Logged
Shane@StumpWare.com
Guest
« Reply #10 on: December 08, 2009, 01:27:04 AM »

BTW ... to pass Session IDs between your custom client and your RTC Server, I would recommend using the same way RTC SDK does it. And that is by using the "ID" query parameter as part of the URI sent from the Client to pass the SessionID to the Server, and using the "ID" cookie on the Client side to receive the SessionID from the Server.

So would the following session strategy work:

Client calls my remote function OpenSession() and I return a SessionID.
Client uses SessionID in all remote functions...
Client calls my remote function CloseSession()  when done or the session expires.

Is that what you are saying? Sorry be a little obtuse, but I want to make sure I do it properly!

And I am assuming that the server's AutoSession property = False!

Merry Christmas & Happy New Year!

SHane
Logged
D.Tkalcec (RTC)
Administrator
*****
Posts: 1881


« Reply #11 on: December 08, 2009, 01:40:26 AM »

What I actually meant was that when you use OpenSession() from inside the OnExecute event of a remote function called on the RTC Server by a Client, then your RTC Server will send the SessionID back to the Client inside the HTTP header as a cookie with the name "ID" and you can pass the same "ID" back from the Client to the Server by adding it to your "URI" on the Client when making a call.

For example, using http://127.0.0.1/myfunc?ID=12345 to send "12345" as the current clients Session ID to the Server,  so the Client would look just like an ordinary RTC Client to the Server and the Server would Find and Lock the Session for the Client automatically on each remote call as long as the Client includes the "ID" parameter inside its URL when making the call.

In other words, the RTC SDK on the Server side will automatically Find and Lock the Session according to the "ID" parameter sent as part of the URL from your Client, and your Client can update its "SessionID" locally if it receives a new cookie from the RTC Server with the name "ID".

If you do not want to do it that way, you can also ignore this whole session synchronization mechanism used by the RTC SDK and pass your Session IDs back and forth as part of your remote function data. In other words, the client can also send its current Session ID to the Server as part of its remote method call parameters, and the server can send a Session ID back to the Client as part of its result data.

Best Regards,
Danijel Tkalcec
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Valid XHTML 1.0! Valid CSS!
Page created in 0.03 seconds with 17 queries.