IpHttpClientChannel's OnLoginNeeded being called constantly (2024 issue)

I have a .NET RO client server setup based on a (TLS enabled) IpHttpClientChannel.
The software runs OK but at some point (timeout or particular network condition) it keeps firing the SessionNotFondException which calls the OnLoginNeeded event.

I probably am do something in code which RO does not support.
For instance

  1. immediately after I set up my IpHttpClientChannel I set up the OnLoginNeeded event after which I explicitely call a Login function via
      var itfLogin = OffCloudServer.CoCloudPharmacyLoginService.Create(roCon.message, roCon.clientChannel);
...
      bool bRet=itfLogin.Login(curSessionUser, jsonLoginData);

I do this so my “connect” function immediately knows if the connection/credentials are OK.
Notice however that the same channel is used which already has the OnLoginNeeded event set. Could this raise the event? Is this allowed code?

  1. My OnLoginNeeded event does not request the user for credentials. It simply provides already available credentials and performs the Login calls displayed above. The code will always set Retry=true if LoginSuccessful=true (see below)
private void ClientChannel_OnLoginNeeded(object sender, RemObjects.SDK.LoginNeededEventArgs e)
{
  if (roCon_ == null)
    return;
  // Performing login
  bool bLoginOK = this.performLogin(true);
  if (bLoginOK)
  {
    e.Retry = true;
    e.LoginSuccessful = true;
    return;
  }
} 

Note: I can reproduce the issue right now in my debugger.
It’s an ideal moment to look at the issue IMO.
I can’t really figure it out myself since some variables are optimized out for the ClientChannel.cs code.

I do see however that the codepath underneath is taken

catch (SessionNotFoundException e)
{
		Boolean loginAttemptResult;
		this.TriggerOnLoginNeeded(e, out loginAttemptResult);
		if (loginAttemptResult)
		{
				requestStream.Seek(0, SeekOrigin.Begin);
				retry = true;

Any tips/suggestions?

An update:
After messing in the debugger (trying to figure out how many events are attached to the OnLoginNeeded eventhandler) due to this or a timeout the endless loop has stopped.

Attached is my debugger Output window log, line 13606 is where I started debugging.
Line 13790 is caused by my watch expression.
20240229offcloud_debugger_w10develfv.txt (1.2 MB)

Additional update:
Still without having restarted any process the issue has returned.
It looks like an endless loop.
I can also say that some threads/channels to the same server keep working fine
but there is again one call that is unable to leave the class ManagementService_Proxy : BaseDataAbstractService_Proxy function. The breakpoints in the screenshot never get hit.

Looking at the RO code it seems paramount that the result of TriggerOnLoginNeeded (which is true and which results in a retry) guarantees with 100% certainty that the session now exists.

The endless loop can be explained if this is not the case.
Where are these sessions maintained? Server side?
What guarantees that it exists? Any succesful call to any function on the channel?
What could destroy the session, only an explicit DestroySession() call?
FYI: Server side I have set breakpoints on all my DestroySession() calls and none get hit.

Hi,

typical code can be like

 private Boolean Login(String loginString)
 {
     ILoginService loginService = CoLoginService.Create(message, channel);
     return loginService.LoginEx(loginString);
 }

 private void channel_OnLoginNeeded(object sender, LoginNeededEventArgs e)
 {
     String loginString = this.GetLoginString(CONNECT_TO_RELATIVITY_SERVER);
     e.LoginSuccessful = this.Login(loginString);
     e.Retry = true;
 }
 this.channel = new RemObjects.SDK.IpHttpClientChannel();
...
 this.channel.OnLoginNeeded += this.channel_OnLoginNeeded;

Note: calling Login manually can be skipped - it will be fired from channel_OnLoginNeeded event automatically.

You can review any DataAbstract for .NET sample. it contains above code.

if you call unprotected service (Service.RequireSession is false), OnLoginNeeded won’t be raised. so your code is ok.

Can you create a simple testcase that reproduces this case, pls?
Your code may contain something that may cause issue.

yes, client-side can’t have any influence to sessions.

Service.DestroySession:

Destroys and disposes the current session.

This method is widely used in the login services to destroy the user session after logout or in case the login attempt was not successful.

I have checked the message.ClientID on the server side and I notice this is not the same as what I see in the login service on the server side.
See screenshots.
How could this be? Could this be the cause?

Hi,

looks like something is wrong on your side:

testcase:
29496.zip (16.0 KB)

I think I found the cause.

The OnLoginNeeded event comes with a an argument sender which contains the client channel.
This channel was different from the channel in my parent object which owned the client channel of the request.
In effect the Login function was called successfully on another channel for another session id.
After this the original call gets retried but still no verified session exists for that session id.

Never accepting the login if the channel does not match is an addition which solves my issue

1 Like