Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Indy Conceptual Question - HELP please! (long)

0 views
Skip to first unread message

Windopaene

unread,
Sep 7, 2001, 1:47:22 AM9/7/01
to
OK, so I was having a situation where it appeared that
ReadLn wasn't. I have now figured out what was happening,
and it is not good for me. Let me describe the conceptual
questions it has raised.

Background
I'm trying to write a server application which CAN be
thought of as a chat program in some regards. When first
arriving in the client application, you see what appears to
be a chat system. There are different "rooms" which the
client can enter. Now these aren't really chat rooms, but it
is a nice analogy. So when a user enters a "room" I am
setting a parameter in a modified TSimpleClient that
identifies the room they are in. Once all of the clients
have entered the room, I want to have a stateful, controlled
process of events occur. So at the point the room task
begins, I am creating a room controller object. This object
gets passed a copy of the clients in the task's room, as
well as the TCPServer. The client's "chat window", gets
replaced by a standard GUI form. The task controller then
gets "executed", and begins looping through the task list
that it has been setup to perform. So far so good. Most of
these will send commands to the client applications, which
they interpret and use to display data and update the GUI.

Now comes the bad part. At several points in the task lists,
I need to be able to get information from the clients.
Mostly, this is working good as well. However, there are
times when the server needs the clients to respond in a
particular order, and not ask client #2 for a response until
client #1 has responded, (as client #2 may modify their
response based on the response of client #1). SO to
accomplish this, on of the task actions will send a command
to client #1, (let's call this command GetResponse).
GetResponse will take information coming in, and present it
to client #1, and wait for a response from client #1. Then
it will do the same for each client in turn.
Now I was originally using this construct

thisResponse := '';
while thisResponse = '' do begin
thisResponse
:=ReadResponseFromClient(currentClient);
end;
{then do some processing and go to the next client}

Where ReadResponseFromClient used the passed index to
find the TSimpleClient in the controllers list and then do a
ReadLn on the client. This would work a few times, but after
going to several clients it would stop and the thisResponse
variable was always containing ''. So then I replaced the
above by using ReadLnWait. This didn't help either. After a
lot of head scratching I finally figured out what was going
on. In the TCPServer.Execute, there was a readLn as well,
and this was getting the buffer contents before the
controller's ReadResponseFromClient could get to it. Now
what I can't figure out why this works sometimes, (always
for the first client), and THEN stops working, but that
doesn't seem totally revelant to making it stop.

So now I'm scratching my head trying to figure out how to
get this to work. I've come up with a couple ideas, none of
which seem very good to me. Idea #1: Have the controller
object create it's own TCPServer, using a different port,
and somehow pass this information to the client app, and
have it make a new connection to the new server.
Idea #2: Add additional code in the current
TCPServer.Execute that will bypass the ReadLn that is there.
Now what I don't know yet is whether doing this will allow
the buffer to "pass-through" to the controller's ReadLn or
not.

Idea #3: Have the controller override the TCPServer.Execute,
and only call inherited if the PeerThread is a member of the
controller's task room client list. I just thought of this
as I was typing, so I haven't considered why this is a bad
idea.

Idea #4: Scrap the whole conceptual framework and do it all
in a different way.

Another problem I can see coming is that I want each
controller object to be created in it's own thread, (so that
one controller in it's execute loop won't prevent other
controller's from running their loops as well). My knowledge
of what you can and can't do with threads is somewhat
limited, but I have my doubts as to my ability to easily
communicate from the Server applications main thread to the
controller threads. This was part of Idea #6 where I was
going to let the server portion put the client response into
a variable, which the controller object(s) (threads), could
then access via a critical section or some other thread safe
manner.

Anyway, if anyone has stuck with this this long, please tell
me your ideas and comments on this, as I'm severely
depressed by this failure, and just really have no idea as
to how to proceeed. I don't want to blow another week's
effort only to hit another roadblock and have to scrap the
whole thing then, so any ideas at all will be greatly
appreciated.

Thanks for reading
Windopaene


Martin James

unread,
Sep 7, 2001, 2:45:03 AM9/7/01
to

Windopaene <Windo...@yahoo.com> wrote in message
news:3B985F6A...@yahoo.com...

> OK, so I was having a situation where it appeared that
> ReadLn wasn't. I have now figured out what was happening,
> and it is not good for me. Let me describe the conceptual
> questions it has raised.
<snip>

This is not really Winsock, but more 'real-time multiuser, mutlitasking
design'. You have to do some design for this app. Readlns in threads and
VCL is not good. Your data seems like it could do with some organisation.
You have clients & rooms. Clients can be outside or in any one room. Once
in a room, clients can engage in a protocol with other client within the
room. The protocol allows for multiple bindings - a client may be
communicating with more than one client at once, conforming to some 'task
rules'.

Start with the data. Work out what entities you need & what fields belong
to what entity Then the thread/process design. The code writes itself
then, (LOL).

I do not think that anyone could scetch out a design for your app. without
something like a requirement/functional spec :)

Rgds,
Martin


Windopaene

unread,
Sep 7, 2001, 2:46:05 AM9/7/01
to
Well I have the app finished actually, (OK well other than the threading), and
was just testing when boom. Hit this snag. Can't figure out a way around it. Did
all of that stuff before and it works great, EXCEPT for this waiting issue...

Kudzu - Team Indy

unread,
Sep 7, 2001, 7:14:13 AM9/7/01
to
"Martin James" <jame...@nortelnetworks.com> wrote in
news:3b986c64_2@dnews:
> This is not really Winsock, but more 'real-time multiuser, mutlitasking
> design'. You have to do some design for this app. Readlns in threads
> and VCL is not good. Your data seems like it could do with some

Actually it is very good design to use threads and ReadLn. It abstracts your communication
code.

--
Chad Z. Hower (Kudzu) - http://www.pbe.com/Kudzu/
Current Location: St. Petersburg, Russia
"Programming is an art form that fights back"


Martin James

unread,
Sep 7, 2001, 7:50:44 AM9/7/01
to

Kudzu - Team Indy <cha...@pbe.com> wrote in message
news:Xns91159AC9D20...@207.105.83.65...

> "Martin James" <jame...@nortelnetworks.com> wrote in
> news:3b986c64_2@dnews:
> > This is not really Winsock, but more 'real-time multiuser, mutlitasking
> > design'. You have to do some design for this app. Readlns in threads
> > and VCL is not good. Your data seems like it could do with some
>
> Actually it is very good design to use threads and ReadLn. It abstracts
your communication
> code.

In contention in two different threads? Naww...

Martin :)


Windopaene

unread,
Sep 7, 2001, 11:35:53 AM9/7/01
to

Well, conceptual debates about the merits of using threads and readln
aside, any ideas as to how to solve my problem or comments of the
efficacy of the various solutions I'm considering?

Ronald Eckersberger

unread,
Sep 7, 2001, 1:44:22 PM9/7/01
to
Hi,

one solution would be the use of a TCPServer and n TCPClient. These talk
to each other via ReadLn(with a time out of x milliseconds).

So when your controllerobjects encounters a waitcondition, than you
allow den server to read x times for y periode. When no usefull data
arrived throw an error and enter an error protocol.

When useful data arrived (non empty string) -> check for right content
of the string. If wrong data -> reread or if the complete time frame was
done -> throw an error. Enter an error protocol.

In other words let indy handle TCP/IP and programm the whole logic
within the execute. Create Command Objects which are able to decode
encode and verify strings. Create your Controllogic Objects. Create the
Error and Keep Alive Objects. Than test the uml design. Than implement.

enjoy,
Ron.

Windopaene

unread,
Sep 7, 2001, 2:40:03 PM9/7/01
to
OK, several responses seem to be missing the boat here. I am using Indy.
The apps are working except for this one situation. I've been doing some
work this morning, and it appears that by adding another flag to the
TSimpleClient, I am able to prevent the TCPSErver Execute from eating
the contents of the buffer, and the Controller object is getting the
buffer instead. I'm hoping this will hold up...

Intersting thought about adding an "error protocol" type handling. Not
sure it directly applies here, but it might be workable for certain
aspects that I haven't fully addressed yet. Thanks

Kudzu - Team Indy

unread,
Sep 9, 2001, 4:55:32 AM9/9/01
to
"Martin James" <jame...@nortelnetworks.com> wrote in news:3b98b40b_1@dnews:

> In contention in two different threads? Naww...

It depends what the contention is. You can easily write from one thread and read from another.
You can even read from multiple threads on a single socket if you do it correctly.

0 new messages