Author | Server calling functions on client |
Leif Uneus 09.01.2007 22:16:51
Registered user |
In the documentations about RtcFunctionGroup it says : "When used by a RtcClientModule, it gives server the ability to call client-side functions as a result of client's function calls."
How is that accomplished on the server ? // My server's MyFunction.OnExecute event procedure TMyServerDataModule.MyFunctionExecute( Sender: TRtcConnection; Param: TRtcFunctionInfo; Result: TRtcValue); begin // At this point I need to call a function on the client // Something like Call( MyClientResult) with some information to the client. // Since this is non-blocking, tell the client I'm working on it. Result.asString:= 'Work in progress ...'; end; // My server's MyClientResult.OnReturn procedure TMyServerDataModule.MyClientResultReturn(Sender: TRtcConnection; Data, Result: TRtcValue); begin IF (Result.isType = rtc_Exception) OR (Result.isType = rtc_Null) THEN BEGIN // Tell the client that the job failed END ELSE BEGIN // Process the result // Tell the client the result of the job END; end; |
Glynn Owen [RTC] 10.01.2007 00:47:15
Registered user |
The help for the TRtcFunctionGroup component says -
<quote> To implement remote functions, you will need at least one FunctionGroup component and link one or more TRtcFunction components to it. Function Group provides the means to use function calls as parameters to other function calls from the same group. It is primarily used by the TRtcServerModule and TRtcClientModule components to hold implementations for their remote functions. This FunctionGroup will provide direct access to: 1.) all functions which have this component as their ".Group" property set. 2.) all functions of all child RtcFunctionGroups, meaning: RtcFunctionGroup components which have this component assigned to their "ParentGroup" property. 3.) all functions of the RtcFunctionGroup which is directly assigned to this component's "HelperGroup" property, including its child components. It is safe to assign the same HelperGroup to function groups at different levels (child/parent groups). </quote> What this does is allow function calls to the server made by the client to use other functions that are on the server. Since function calls are also objects, it also allows you to send a function call from Servers OnExecute event back to the client as Server's result. As with any other Result sent from the Server back to the Client, it will NOT be sent back to the Server, but instead (after any functions placed in that result have been executed on the Client) the resulting object will be sent to the OnResult event of the Client. Once MyFunctionExecute has assigned something to the Result, the function is done, so I guess that what you are looking for is some way to notify the client that some kind of lengthy process is in progress. Is that right? Have you looked at the examples in the QuickStart folder? HTH, Glynn |
Danijel Tkalcec [RTC] 10.01.2007 02:54:21
Registered user |
Let me elaborate a bit on this ...
1) A Server can not directly "Call" a function on the Client and expect a result to get back, since the request/response cycle will be completed once the Client has received a response from the Server. What a Server can do is "return" an object which has Remote Function call objects in it, which you can create the same way you prepare a remote function call on the Client (by using the newFunction method). So, your Server will prepare a Result in which Function objects will be stored by using the newFunction() method. If the Client (which called that Server-side function) has these functions implemented locally (and assigned to the ClientModule in a FunctionGroup), then the Client will execute these functions and pass the final result data (after all functions have been executed locally) to the Client's local OnResult event (parameter used in client's Call method). As you see, in this event, there will be no data sent back to the Server. Instead of that, the resulting data will be sent to your Client's OnResult event. This allows the Server to send a result in which parts which will be calculated on the Client-side, using Client-side functions known to the Server. This can be useful if you want to keep most of the business logic on the Server, but are holding some data segments on the Client. 2) If you want your Server to be able to call remote functions on the Client side (as explained above), what you need to do on the Client is assign a RtcFunctionGroup to your RtcClientModule and assign the client-side RtcFunction components to that FunctionGroup. After you have done that, what you can do is call Remote Functions on the Client from OnExecute events on your Server, simply by creating a Function object in your Result. So, for example if you have implemented a function on the Client called "CliFunc", which you want to be able to call from the Server as a result of a function called from that Client, you would write your Server's OnExecute event like this ... with Result.newFunction('CliFunc') do
begin asString['par1']:='Test'; end; What will happen then, is that your ClientModule will receive this Result object and "execute" it by calling all remote functions implemented locally, before passing the resulting parameters to the OnResult event. 3) In your code example, what you would do is ... (a) implement the function on the Client-side which you want to call from the Server, (b) call a function on the Server-side which will be sending a "Function" object back to the Client, either as one object or as any parameter or value inside the complex result structure. Your Server-side implementation could look like this ... // My server's MyFunction.OnExecute event
procedure TMyServerDataModule.MyFunctionExecute( Sender: TRtcConnection; Param: TRtcFunctionInfo; Result: TRtcValue); begin // As a result, I want to call a function on the client with Result.newFunction('ClientsFunctionName') do begin // prepare function call parameters ... asString['param1']:='Data1'; asInteger['x2']:=12345; end; end; 4) I'm not sure what you wanted to accomplish, but it does look like a complex ping-pong game between your Clients and your Server. If you could explain what you wanted to achieve, we would have a better understanding of your problem and a better chance to point you in the right direction. As for now, I can not imagine any situation where your scenario would be needed, since all the data you require from the client for any remote function call can be sent from the Client to the Server as parameters. But, if you can elaborate more on the reasons why you think you wanted to do this, we may be able to propose a different method for solving your problem, or extend the RTC SDK to allow doing what you wanted to do. Best Regards, Danijel Tkalcec |