Reuse of Remoting Channels...
From: Rob Jones (rjones_at_bak.rr.com)
Date: 03/24/05
- Next message: Serg: "Re: Is there any way to call event/callback from server to client if client is behind proxy?"
- Previous message: Fred Hirschfeld: "Re: C# remote server and host application"
- Messages sorted by: [ date ] [ thread ]
Date: Thu, 24 Mar 2005 14:50:57 -0800
Although my question pertains to remoting within .NET 2.0, I'm posting
my question here because:
1) There's not much activity in MS's private newgroups for .NET 2.0.
2) I think my question is not all that specific to features present
in .NET 2.0 (and missing from .NET 1.1).
So, here goes:
As some of you may know, one of the neat new features in .NET 2.0 is
the added credentials / security available in the TCP channels. This
makes it possible for the server to know the identity of the caller.
This is a feature that I am taking advantage of in my code, and is
related to my problem.
If my client is on the other side of a Windows 'realm' (as in the
client is logged into a Windows domain and the server is not a member
of the same domain) my server code has been instructed (via its
RemotingConfiguration options) to reject any clients whose credentials
the server cannot authenticate. When this happens, my client is
thrown an exception that says "you need to provide credentials that
the target server can authenticate". So, my client then fetches
username and password info from the user (presumably credentials that
the server can authenticate) and the client code then trys to
re-establish a connection with the server. Herein is where my problem
lies. I've discovered that if the client initially provides valid
credentials, all works fine. However, if the first connection attempt
throws the exception mentioned above, any subsequent connection
attempts fail also (even when valid credentials were provided). It's
as if once the client establishes that first connnection with the
remote server, the credential info provided is 'retained' and I can't
seem to clear it out.
Below I've posted the code that gets called each time the client tries
to connect. Note that each time through I check to see if any
channels are already registered and if so, I unregister them.
However, that doesn't seem to be enough.
If anyone has any clues / ideas, I'd be most grateful.
TIA
Rob
=================================================================================
private ILightspeedServices Connect(ref ClientChannelData myChannel,
ref ConnectionError myError, ref string strSystemErrorMessage)
{
int iLoopCount = 0;
int iLoopExit = 2;
string strRemoteURI = "";
if ( Global.IsServerLocal(myChannel.Server) )
strRemoteURI = String.Format
(
@"{0}://{1}/{2}",
myChannel.Name,
myChannel.Port,
myChannel.ObjectUri
);
else
strRemoteURI = String.Format
(
@"{0}://{1}:{2}/{3}",
myChannel.Name,
myChannel.Server,
myChannel.Port,
myChannel.ObjectUri
);
// If there are any registered channels left over from
previous attempts, unregister them now.
foreach (IChannel thisChannel in
ChannelServices.RegisteredChannels)
{
ChannelServices.UnregisterChannel(thisChannel);
}
// Select the correct channel...
switch (myChannel.Name)
{
case ChannelDefaults.TcpChannelName:
TcpClientChannel myTcpChannel = new
TcpClientChannel(myChannel.ChannelParameters, null);
ChannelServices.RegisterChannel(myTcpChannel);
break;
case ChannelDefaults.IpcChannelName:
IpcClientChannel myIpcChannel = new
IpcClientChannel(myChannel.ChannelParameters, null);
ChannelServices.RegisterChannel(myIpcChannel);
break;
}
// If this is the first pass, we must initialze everything.
Otherwise, just change those parameters of
// each WellKnownClientTypeEntry that was registered during
the first pass...
WellKnownClientTypeEntry[] entryArray =
RemotingConfiguration.GetRegisteredWellKnownClientTypes();
if (entryArray == null || entryArray.Length == 0)
{
WellKnownClientTypeEntry myEntry = new
WellKnownClientTypeEntry(typeof(ILightspeedServices), strRemoteURI);
RemotingConfiguration.RegisterWellKnownClientType(myEntry);
}
remoteLightspeedServices =
(ILightspeedServices)Activator.GetObject(typeof(ILightspeedServices),
strRemoteURI);
do
{
strSystemErrorMessage = "";
try
{
if (remoteLightspeedServices.TtcServiceControl
!= null)
return (remoteLightspeedServices);
}
catch (System.Net.Sockets.SocketException socketEx)
{
switch (socketEx.ErrorCode)
{
// No credentials provided...
case 10054:
myError =
ConnectionError.MissingCredentials;
strSystemErrorMessage =
socketEx.Message;
break;
// Remoting server cannot be
reached...
case 10060:
myError =
ConnectionError.UnresponsiveServer;
strSystemErrorMessage =
"Remoting server cannot be reached. " + socketEx.Message;
break;
// Remoting server appears to be
alive, but we can't seem to find LightspeedServices service
case 10061:
myError =
ConnectionError.NoServer;
strSystemErrorMessage =
socketEx.Message;
break;
// Remoting server's name cannot be
resolved...
case 11001:
myError =
ConnectionError.UnknownServer;
strSystemErrorMessage =
"Remoting server's name does not exist. " + socketEx.Message;
break;
default:
myError =
ConnectionError.Unknown;
strSystemErrorMessage =
socketEx.Message;
break;
}
}
catch
(System.Security.Authentication.InvalidCredentialException
credentialsEx)
{
// Bad credentials provided...
myError = ConnectionError.BadCredentials;
strSystemErrorMessage = credentialsEx.Message;
}
catch (System.Runtime.Remoting.RemotingException
remotingEx)
{
// We handle this error as if the remoting
server is not running...
myError = ConnectionError.NoServer;
strSystemErrorMessage = remotingEx.Message;
}
catch (Exception generalEx)
{
myError = ConnectionError.Unknown;
strSystemErrorMessage = generalEx.Message;
}
// If we're here, something went wrong. Can we do
anything about it???
switch (myError)
{
// Maybe we can start the remote server???
case ConnectionError.NoServer:
RestartLightspeedServicesService();
break;
// All other errors, just go back with an
exception...
default:
iLoopCount = iLoopExit;
break;
}
}
while (++iLoopCount < iLoopExit);
// nothing has worked, so go back empty handed...
return null;
}
=========================================================================
- Next message: Serg: "Re: Is there any way to call event/callback from server to client if client is behind proxy?"
- Previous message: Fred Hirschfeld: "Re: C# remote server and host application"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|