Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 8 of 8 total
Thread Questions about Server Side Procedures
Sat, Feb 18 2006 8:59 PMPermanent Link

"Johnnie Norsworthy"
I have a web-based DBISAM 4 server. I'm just starting writing some server
side procedures to replace some web services I currently use to update this
database.

When a a client calls a server side procedure with a couple of parameters, I
need to record the client's IP address, and the  parameters in a database
stored on the server.

First question: How do I determine the client's IP address in  the server
side procedure, using ServerSession.RemoteAddress?

TMainForm.ServerEngineServerProcedure(Sender: TObject;
 ServerSession: TDBISAMSession; const ProcedureName: string);

Second question: When modifying the server source code, can I just drop a
table or query component and a session component on the server and use it to
access the server tables? If so, I assume that session would have to be
configured as remote and use 'localhost' and not a local connection. Do I
need to worry about dynamically creating these components?

One more question: Is there any way to push data from the server to an
individual remote session or all sessions and have an event fire for them?
For example, I could make a remote procedure that sends all active clients a
text message when server maintenance will be done.

Thanks for any answers. I am setting up a separate machine on my network to
help with these debugging and test issues, but it is not working correctly
yet. If these server-side procedure work out, I don't see any reason I'd use
web services, as I would assume this method would be faster.

Johnnie

Sun, Feb 19 2006 8:13 PMPermanent Link

Oliver Bock
Hi Johnnie,

> First question: How do I determine the client's IP address in  the server
> side procedure, using ServerSession.RemoteAddress?
>
> TMainForm.ServerEngineServerProcedure(Sender: TObject;
>   ServerSession: TDBISAMSession; const ProcedureName: string);

Implement OnServerConnect and store the user's address in a threadvar.

Fetch it out when you need it in OnServerProcedure.

> Second question: When modifying the server source code, can I just drop a
> table or query component and a session component on the server and use it to
> access the server tables? If so, I assume that session would have to be
> configured as remote and use 'localhost' and not a local connection. Do I
> need to worry about dynamically creating these components?

I haven't tried this, but I think it would be a bad idea because each
thread needs its own TDBISAMDatabase, etc.  I use pure Pascal to create
the objects I need when I need them.  I use the session provided to
OnServerProcedure.

> One more question: Is there any way to push data from the server to an
> individual remote session or all sessions and have an event fire for them?
> For example, I could make a remote procedure that sends all active clients a
> text message when server maintenance will be done.

The short answer is no, but I can think of some klunky alternatives:

1. Have all remote applications poll the server regularly.
2. Manually set up your own socket connection between clients and hosts.
3. Have each remote application launch a thread and make a server
   procedure call that does not return until the next event occurs.

> Thanks for any answers. I am setting up a separate machine on my network to
> help with these debugging and test issues, but it is not working correctly
> yet. If these server-side procedure work out, I don't see any reason I'd use
> web services, as I would assume this method would be faster.

It might be easier to get your client/server stuff working on just one
machine.  You can test it on separate machines later.


   Oliver
Sun, Feb 19 2006 11:23 PMPermanent Link

"Johnnie Norsworthy"

"Oliver Bock" <oliver-elevatesoft-news@ikucwe.com> wrote in message
news:A33D27CB-D8AB-4BD2-9BD4-FE830CA4963A@news.elevatesoft.com...
> Hi Johnnie,
>
>> First question: How do I determine the client's IP address in  the server
>> side procedure, using ServerSession.RemoteAddress?
>>
> Implement OnServerConnect and store the user's address in a threadvar.
>
> Fetch it out when you need it in OnServerProcedure.

I don't quite follow this? Where do I create the variable to have it
accessible in both places that will not be affected by other new
connections?

>> Second question: When modifying the server source code, can I just drop a
>> table or query component and a session component on the server and use it
>> to access the server tables? If so, I assume that session would have to
>> be configured as remote and use 'localhost' and not a local connection.
>> Do I need to worry about dynamically creating these components?
>
> I haven't tried this, but I think it would be a bad idea because each
> thread needs its own TDBISAMDatabase, etc.  I use pure Pascal to create
> the objects I need when I need them.  I use the session provided to
> OnServerProcedure.

OK. Good to know.

>> One more question: Is there any way to push data from the server to an
>> individual remote session or all sessions and have an event fire for
>> them? For example, I could make a remote procedure that sends all active
>> clients a text message when server maintenance will be done.
>
> The short answer is no, but I can think of some klunky alternatives:
>
> 1. Have all remote applications poll the server regularly.
I don't want to do this for performance issues.
> 2. Manually set up your own socket connection between clients and hosts.
I might look into this later.
> 3. Have each remote application launch a thread and make a server
>    procedure call that does not return until the next event occurs.
I have seen how this would work due to some buggy code I wrote, but it seems
like it would affect perfomance as well.

>> Thanks for any answers. I am setting up a separate machine on my network
>> to help with these debugging and test issues, but it is not working
>> correctly yet. If these server-side procedure work out, I don't see any
>> reason I'd use web services, as I would assume this method would be
>> faster.
>
> It might be easier to get your client/server stuff working on just one
> machine.  You can test it on separate machines later.

I got my machine and another on my network set up with a server for testing.

It seems that the command line server doesn't work when I try to log in to
the admin port for some reason. And this is the one I will need to deploy to
my web server. I haven't had any problems with the GUI server with the code
I added.

Thanks for your reply. I have a bunch to learn on this subject that I will
have to do in the next couple of weeks, but I could see the remote procedure
calls replacing a bunch of web services I have right now.

-Johnnie

Mon, Feb 20 2006 10:40 AMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Johnnie,

<< I don't quite follow this? Where do I create the variable to have it
accessible in both places that will not be affected by other new
connections? >>

All connections are thread-based, meaning that there is one connection per
thread.  So, using a threadvar is a way of ensuring that each thread gets
its own "copy" of the variable for its own private use.  If you assign the
IP address to this threadvar in the OnServerConnect event handler, then you
can then retrieve it in the OnServerProcedure event handler because both are
running in the same thread still.


<< I have seen how this would work due to some buggy code I wrote, but it
seems like it would affect perfomance as well. >>

Not if you did it correctly.  However, it won't be particularly simple.
Basically you need to have the OnServerProcedure put the thread "to
sleep" by having it wait forever (or within a timeout period) on an event
that can be raised by other threads.  That will "wake up" the thread and
allow it to do what ever you wish next.

<< It seems that the command line server doesn't work when I try to log in
to the admin port for some reason. And this is the one I will need to deploy
to my web server. I haven't had any problems with the GUI server with the
code I added. >>

What exactly is happening ?  Is it allowing you to log in ?

--
Tim Young
Elevate Software
www.elevatesoft.com

Mon, Feb 20 2006 1:06 PMPermanent Link

"Johnnie Norsworthy"
"Tim Young [Elevate Software]" <timyoung@elevatesoft.com> wrote in message
news:DA667943-744A-4CF9-A388-B27A8E4B477E@news.elevatesoft.com...

> All connections are thread-based, meaning that there is one connection per
> thread.  So, using a threadvar is a way of ensuring that each thread gets
> its own "copy" of the variable for its own private use.  If you assign the
> IP address to this threadvar in the OnServerConnect event handler, then
> you can then retrieve it in the OnServerProcedure event handler because
> both are running in the same thread still.

So, I just define (in the dbcmd project):

ThreadVar
 IPAddress: string;
(I have never used ThreadVar before, so pardon my denseness)

> << I have seen how this would work due to some buggy code I wrote, but it
> seems like it would affect perfomance as well. >>
>
> Not if you did it correctly.  However, it won't be particularly simple.
> Basically you need to have the OnServerProcedure put the thread "to
> sleep" by having it wait forever (or within a timeout period) on an event
> that can be raised by other threads.  That will "wake up" the thread and
> allow it to do what ever you wish next.
I'll probably end up using the polled approach, once a minute, calling a
server procedure. Could I just set a global in one procedure and read it
from the others?


> << It seems that the command line server doesn't work when I try to log in
> to the admin port for some reason. And this is the one I will need to
> deploy to my web server. I haven't had any problems with the GUI server
> with the code I added. >>
>
> What exactly is happening ?  Is it allowing you to log in ?
This is resolved. I think there was just some issue with me trying to
connect to three different servers: my hosted web server, my LAN server, and
then a localhost server. It may just be an issue with DbiDesktop, which I
was using.

DBISAM Server Procedures are more fun than web services. Smiley

Thanks,

Johnnie

Mon, Feb 20 2006 6:49 PMPermanent Link

Oliver Bock
Johnnie Norsworthy wrote:
> So, I just define (in the dbcmd project):
>
> ThreadVar
>   IPAddress: string;
> (I have never used ThreadVar before, so pardon my denseness)

That should work.

> I'll probably end up using the polled approach, once a minute, calling a
> server procedure. Could I just set a global in one procedure and read it
> from the others?

Yes, but do consider threading issues:

- Ensure that your global variable contains no more than a single
  32 bit value, so that it will be written atomically.
  If you need more than one piece of information then stick them
  in a class.
  (The problem we are trying to avoid occurs when you have
  multiple global variables, and a reading thread finds them
  half way through a change.)
  You could also use a TCriticalSection to avoid the problem.

- Consider what will happen if you change the global variable
  twice before a thread gets a chance to see it.
  That is, the thread should not mind missing some "events".

- Ensure that you don't destroy the information provided via
  the global variable until you are sure the threads are
  finished with it.


   Oliver
Mon, Feb 20 2006 8:19 PMPermanent Link

"Johnnie Norsworthy"
Oliver,

Thanks for this information.

I have been hacking away with some server side procedure stuff today
including the IP address recording, which is all I have to do for the my web
database. It appears to be working and storing my computer IP like I want,
but I haven't tried it on my hosted web server yet.

The local databases which will run on my client's LANs will have a few more
server side procedures, including the polled messages for clients.

So far this is all working out pretty good and I see lots of possibilities.

Thanks again,

-Johnnie

Tue, Feb 21 2006 12:45 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Johnnie,

<< I'll probably end up using the polled approach, once a minute, calling a
server procedure. Could I just set a global in one procedure and read it
from the others? >>

I would recommend simply using a table for populating the "messages" that
you want others to read.  You can even specify a specific user to direct
messages to, etc.

--
Tim Young
Elevate Software
www.elevatesoft.com

Image