Products

Price/Order

Support

Partners

Testimonials

Test Results

About us

Contact
 Running as a DLL
Bottom
 
Total posts: 6
 Author Running as a DLL
Zane LEO

24.10.2009 07:06:42
Registered user
I have an RTC Server and Client application that works perfectly with both Server and Client run as EXE's.

I then converted the Client to a DLL. The Client.DLL will be used as an API.

For testing purposes I created a very small EXE that does only loads and unloads Client.DLL (at this stage) and all functionality (for testing) is then operated from the Client.DLL GUI.

Problem is this....

When I log in to the Server from the EXE all works perfectly BUT when I log in to the Server from the DLL, The DLLdoe not receive the response from the Server but the Server has sent it.

Any suggestion on where I am going wrong?

A code extract:

procedure TForm1.btnLoginClick(Sender: TObject);
begin
  Client.Connect;
  with ClientModule, Data.NewFunction('login') do
  begin
    LogMessage('REQUEST LOG IN', 'Login_1');
    asString['ClientID'] := gv_ClientID;
    asString['User'] := eLoginUser.Text;
    Call(resLogin);
  end;
end;

.
.
.

procedure TFormhPOSClient.resLoginReturn(Sender: TRtcConnection; Data,
  Result: TRtcValue);
begin

  if Result.isType=rtc_Exception then
  begin
    if Client.isConnected then
    begin
      Client.SkipRequests;
      Client.Session.Close;
      Client.Disconnect;
    end;
    LogMessage('Connection Rejected', Result.asString);
  end
  else if Result.isType<>rtc_Record then
  begin
    btnLogoutClick(btnLogout);
    LogMessage('Reg Client', 'Invalid Server Response.');
  end
  else
  with Result.asRecord do
  begin
    gv_ServerSessionID := asString['ServerSessionID'];
.
.
.
.
.
end;


TIA

Zane
Andrew W.

24.10.2009 13:56:49
Registered user
I'm 99.9% sure that the issue is that you need to have a message pump running. If you don't then RTC won't work, and other Delphi things like TTimers will not work either. Quite simply, none of the underlying events on which RTC depends will be passed.

If you are writing a Service application, you must also make sure you are not using Wininet, as stated in the RTC docs this is not compatible with Service applications. Use WinHTTP.

The way I solved this was to have a message pump built into my dll, so that all of my RTC code runs in it's own thread.

Here is some sample code.

procedure TMyTSThread.Execute;
var
        lssMsg: TMsg;
        liResult: integer;
        lusError: RTSError;
begin
        try

        postThreadMessage(ThreadID, SERTIOTSTHREAD_STARTUP, 0, 0);

        while not terminated do
        begin
                GetMessage( lssMsg, 0, 0, 0);

                if lssMsg.hwnd = 0 then
                begin
                        case lssMsg.message of
                                SERTIOTSTHREAD_STARTUP:
                                        begin
                                                // run my rtc server here
                                        end;
                                SERTIOTSTHREAD_QUIT:
                                        begin
                                                // quit and clean up here
                                        end;
                                else begin
                                        TranslateMessage(lssMsg);
                                        DispatchMessage(lssMsg);
                                end;
                        end;
                end else
                begin
                        TranslateMessage(lssMsg);
                        DispatchMessage(lssMsg);
                end;
        end;

        finally
                obDone := TRUE;
        end;

end;
Zane LEO

26.10.2009 07:14:47
Registered user
Andrew

In your code snippet where you have "  // run my rtc server here " do you mean create and instance of the rtcclient / rtcserver?

Danijel, I am surprised that this situation is not covered in the base RTC SDK - or is it? If so then where?
Danijel Tkalcec [RTC]

26.10.2009 10:23:06
Registered user
Zane, I've never tried using the RTC Client components from inside a DLL, but Andrew is correct by saying that you will need a windows message pump if you want to use the asynchronous WinSock API.

The RTC SDK already has a thread with a windows message pump automatically created for you, but it will only be used if you set the MultiThreaded property to TRUE on your RTC components. If you want to use RTC components in single-threaded mode, and you want to use asynchronous communication with the WinSick API, you will need to create the message pump similarly to how Andrew has already explained above.

On the other hand, if you would rather use the RTC Client components in blocking mode, you can simply set the useProxy and/or useWinHTTP properties to TRUE. If you do this, all your methods will be blocking, executed synchronously (nothing will be happening in the background) and a windows message pump will NOT be required by RTC components.

Best Regards,
Danijel Tkalcec
Andrew W.

26.10.2009 11:24:10
Registered user
>>In your code snippet where you have "  // run my rtc server here " do you mean create and instance of the rtcclient / rtcserver?

Yes. My own application runs as a DLL. This is so I can run it from a window in development, but also easily deploy in in a Windows Service in a production environment.

The point I've marked out is where 'My RTC Server' begins it's job of servicing clients - effectively, it's the start point for the application.
Zane LEO

26.10.2009 22:39:31
Registered user
Thanks Danijel,

But the app must run multi-threaded and I do have MultiThreaded property to TRUE on all components. Works perfectly running as EXE but not as DLL. I am testing Andrew's advice.

Thanks Andrew,

My DLL is the RTC Client and the RTC Server (will changed to) a service but I will proceed on the same basis as your server.

Both, thanks again,

Zane