views:

168

answers:

6

Hi , i am writing a simple client/server chat program with indy 10 (blocking mode) and there is a question that how can i manage connections ? for example imagine a user that is online on server , we must make a connection tunnel for future requests . In other words, when a user is online server should not need username and password for future user requests . and it will be do with the tunnel that we created when user has came .

how can we manage connections ?

[sorry for my bad english] if you can't understand me please tell me to send a new post agian .

Thank you

A: 

One option would be to create a unique session ID (or "token") on the server side, for example a GUID, if a client logs in. And in every request, the client includes this token.

The server would maintain a list of client sessions and associated session data, and looks up the token in this list.

Even if a client is temporary disconnected from the Internet but still knows its token, the application can reconnect and continue the session with the server.

mjustin
Thank you for response but imagine , that there are 10,000 online user and each user is sending 10 message per second to the server .so finally we will have 100,000 session ID check in one second . and it will be deadly for server !!
Kermia
When I read 'a simple chat program' I did not think of 10,000 users which are all sending a message every 100 milliseconds :)
mjustin
Oh you right :D . but if we want to using this way for bigger projects ? is it possible ? or you offer another ways ? Thank you mjustin :)
Kermia
Not for Delphi, sorry. Maybe *APE* (free *Ajax Push Engine*, Sourceforge project name *Ajax Chat Engine*), which can handle more than 100,000 users, is an option: http://www.ape-project.org/wiki/index.php/FAQ - the server is written in C
mjustin
A: 

Thank you for response but imagine , that there are 10,000 online user and each user is sending 10 message per second to the server .so finally we will have 100,000 session ID check in one second . and it will be deadly for server !!

Kermia
Hi Kermia, on Stack Overflow, this should be a comment to the answer (instead of using 'Add Another Answer').
mjustin
+2  A: 

For the scenario described in the question, there isn't really much management to do. To avoid having to re-authenticate on every request, simply don't close the connection. In a chat server, especially, it's quite likely that each participant will establish a connection and then continue using that same connection for the duration of the chat.

Indy server objects already keep a list of their open connections, so when you want to broadcast a chat message to the other participants, you can just iterate over that list.

Rob Kennedy
Agreed. You can store per-connection information in the TIdPeerThread.Data (Indy 9 and earlier) and TIdContext.Data (Indy 10) property if you need to persist custom data between requests, such as authentication details. As long as a connection remains open, that information only needs to be collected and stored once per client. If clients disconnect and reconnect between requests (such as in HTTP), then you have to manually track your information from one connection and apply it to the next connection.
Remy Lebeau - TeamB
Thank you ! good answer . finally which way you offer me to manage connections and session IDs with minimum processing ? i think we must send the current Acontext-Index to the client as a session ID and in future requests when session ID received , we will extract the Acontext(connection) index from it and continue communication with this tunnel . isn't it ?
Kermia
No, Kermia. Once the connection is closed, the context object is destroyed. Since you've accepted this answer, there is no need for a session, *per se*. Instead, *the connection is the session*. The client doesn't need to be told anything by the server because as long as the client maintains the open connection, it already has everything it needs. The server also continues to know about the connection, so within your Indy event handlers, you will automatically be given the correct context object for whatever connection the event occurred on.
Rob Kennedy
+1  A: 

I think 100000 checks per second will be the less resource consuming thing, than having 10000 persistent TCP connections. And anyway you will need to process somehow these 100000 commands, so those checks would not be the bottleneck.

Try to use the UDP messages instead. For example, most MMO games use both TCP and UDP connections. TCP only for critical data, and UDP for any other data. In your case UDP seems to be acceptable. The client can send UDP packets with some autoincrement IDs, and the server can periodically send back the list of IDs it doesn't receive, so the client can resend them.

Andrew
A: 

Yes . so we have two options : 1-Using session IDs to check request validation . 2-using a list to save connections for future communications . but question is how can we manage this mass of connections ?

Kermia
A: 

But in Indy 10 we have just an OnExecute Event ! So how will i know which Message is for which connection ? All of the messages will be processing in one event : OnExecute (This is trait of Blocking-mode programming) . may you explain it with a example source code ? also , do not forget "Connected User" is different from "Online User"

Kermia
See http://conferences.embarcadero.com/article/32160, it shows source examples for Indy 10, using `AContext.Connection.IOHandler`. Indy 10 provides a context in the form of TIdContext. The context that is passed into each event is uniquely identified and associated with a specific connection.
mjustin
Thank you mjustin :)
Kermia