[en] How to keep ActiveClients in sync with real sessions (solved)

Topics: Technical Support
Jan 12, 2012 at 10:52 AM

Hi,

in your MiniChat.Server example you are using an 'ActiveNicknames' list to keep a list of actively connected clients. You are using the 'OnClientLoggedOn' and 'OnClientLoggedOff' event handlers to do so.

However, if a client terminates abnormally (and as such doesn't gracefully disconnect from the server), this list gets logically invalid, as the disconnected client of course doesn't provide any effective Loggof event.

However, the session manager might sweep expired sessions automatically. Once this is done, the 'dead' session is removed internally (which i good).

But the MiniChat.Server itself has no info, that this happeded and as such can not manage its 'ActiveNicknames' list accordingly!

The MiniChat.Server also has no possibility to query the 'ActiveSessions', as the 'ISessionManager' interface doesn't provide any access to it.

So how could a 'ZyanComponentHost' (the MiniChat.Server) keep the 'ActiveNicknames' list in sync with the real active sessions?

Coordinator
Jan 13, 2012 at 9:20 PM

Hi,

that's a good question...

Looks like we should extend session manager to be able to track sessions being swept.
Seems like it's the only way to track clients terminated abnormally.

I'd suggest to add a new event for this, similar to ZyanComponentHost.ClientLoggedOff.
Let's wait to hear what would Rainbird say.

Coordinator
Jan 16, 2012 at 7:08 PM

Hi,

an additional ZyanComponentHost.ExpiredSessionRemoved event makes sense. But we should keep in mind, that sessions are security critical. So the Session ID of the removed session should not be published to subscribers of this event.

Logon and logoff can be monitored directly by ZyanComponentHost, but removal of expired sessions is encapsulated in the session manager. The session manager must notify its ZyanComponentHost instance, when a expired session is swept away. This must be done in a asynchronous and decoupled way, because blocking the sweep method - which will happen in case of using ordinary events - may lead to security issues (Someone may delay the removal of further expired sessions).

Another point is backward compatibility to existing ISessionManager implementations. Sweeping of expired sessions is done by the session manager. We can extend the default Zyan ISessionManager implementations with such a new event. But the ISessionManager interface must not be changed. Otherwise custom ISessionManager implementations of many Zyan users won´t work, after they get the newest Zyan source.

The circumstance that the ExpiredSessionRemoved event may not be fired, if the used ISessionManager implementation doesn´t notify the ZyanComponentHost, must be tolerated.

I suggest to create a seperate interface for notification of removed expired sessions, that session managers can implement. ZyanComponentHost can check, if the specified session manager implements this interface and then inject a callback delegate to receive the notification. Let´s call that interface INotifyOnRemoveExpiredSession or something like that.

ZyanComponentHost can also provide a property to query if the used session manager supports notification on expired session sweep, or not.

Coordinator
Jan 16, 2012 at 9:44 PM
Edited Jan 16, 2012 at 10:01 PM

Hi Rainbird,

thanks for your observation!

>an additional ZyanComponentHost.ExpiredSessionRemoved event makes sense.
>But we should keep in mind, that sessions are security critical.
>So the Session ID of the removed session should not be published to subscribers of this event.

It looks to me that it should be EventHandler<LoginEventArgs>,
just like ClientLoggedOn/ClientLoggedOff events.

>Another point is backward compatibility to existing ISessionManager implementations.

Backward compatibility is always a tough question :)

But I'd like to point out that before Zyan 2.2 it was impossible to create a new session manager
from scratch (I've tried it myself, but there were a few internal methods or properties one just could not
access outside the Zyan assembly), so all custom manager were to be derived from the existing ones.

Zyan 2.2 introduced SessionManagerBase class, so now all session managers have it as a root
of their hierarchy. Therefore, I think it's safe to extend ISessionManager interface providing
the new event is implemented in SessionManagerBase.

I believe this straightforward solution is more intuitive and would be easier
to maintain (and also easier to understand for the newcomers).

Coordinator
Jan 18, 2012 at 4:52 AM

Hi yallie,

ok, Point for you. The common base class makes the extension of ISessionManage safe.

Coordinator
Feb 15, 2012 at 9:07 PM

Hi,

I've added ClientSessionTerminated event and updated the MiniChat sample.
Now ActiveNicknames list is kept in sync with active sessions. 

P. S. I didn't use the word 'Expired' because I feel that expiration is not the only possible reason for the session to be terminated abnormally.

Coordinator
Feb 16, 2012 at 6:06 AM

Hi yallie,

the name ClientSessionTerminated makes sense.

Thanks for updating the MiniChat example.

Feb 16, 2012 at 7:38 AM

Thanks guys.

I guess the latest changes will solve all my issues.

THX

Bernd

Coordinator
Feb 17, 2012 at 7:33 AM

Hi Bernd, I'm very glad!

Your feedback was very valuable.

Regards, yallie