Recently, in one of our client environments, we found that the TCP Remoting Service for Client Communication takes 8-10 seconds, but the client communication service occurs immediately.
First I will try to explain what we are trying to do. In our client environment, 30-40 users will be registered on each server, so for this user we will launch the Tray [Client] application, and at each interval from the service we will send a request to the client to capture the current header of the active user and the name of the process after it is captured, then the client will send back data to our service using TCP Remoting.
Then the problem is that 40 users perform one action, which took 7-8 minutes, so we thought about using a thread poll with MaxThreadLimit properties as 3. My doubt is that there may be a delay in servicing the connection with by customer. Here is the code we use
public static List<DataEntity> GetAllUsersData()
{
var complete = new CountdownEvent(1);
var throttle = new Semaphore(3, 3);
foreach (Process UserProcess in AllUsersProcess)
{
activeUser = ActiveUsers.GetInstance().GetActiveUserBySessionId(UserProcess.SessionId);
if (activeUser == null ||
activeUser.UserState == UserStateEnum.LOCKED ||
activeUser.UserState == UserStateEnum.LOGIN_IN_PROGRESS ||
activeUser.UserState == UserStateEnum.LOGOUT_IN_PROGRESS ||
activeUser.IgnoreRoleActivity)
{
activeUser = null;
continue;
}
complete.AddCount();
ThreadPool.QueueUserWorkItem((state) =>
{
throttle.WaitOne();
try
{
GetCurrentUserActivity(userActivities, ProbeOffline, ref userActivity, UserProcess);
Thread.Sleep(300);
}
catch (Exception ex) { log.ErrorFormat("Exeption occcured while getting user activity in threadpool {0}, {1}", ex.Message, ex.StackTrace); }
finally { throttle.Release(); complete.Signal(); }
}, null);
}
complete.Signal();
complete.Wait();
}
This is a method in which we will make a tcp call by deleting all clients.
private static TrayActivityInterfaces GetCurrentUserActivity(List<DataEntity> userActivities, bool ProbeOffline, ref UserActivityEnitity userActivity, Process UserProcess)
{
TrayActivityInterfaces remoteMethods;
try
{
Stopwatch userActivityTime = new Stopwatch();
ActiveUserInfo activeUser = ActiveUsers.GetInstance().GetActiveUserBySessionId(UserProcess.SessionId);
log.DebugFormat("Activity[{0}], Sending the request to get user activity form tray for sessionid: {1}", activeUser.Username, UserProcess.SessionId);
remoteMethods = (TrayActivityInterfaces)Activator.GetObject(typeof(TrayActivityInterfaces), ProbeProperties.ProbeProperties.GetTrayRemotingUrl(UserProcess.SessionId));
userActivity = remoteMethods.GetUserActivity(true);
userActivity.ActivityTime = DateTime.Now;
userActivity.Offline = ProbeOffline;
if (string.IsNullOrEmpty(userActivity.ActiveProcessName))
userActivity.ActiveProcessName = GetTopWindowProcessName(userActivity.ActiveProcessId);
if (log.IsDebugEnabled) log.DebugFormat("Activity[{0}], Received in {1} seconds. User Activity: {2}", activeUser.Username, userActivityTime.Elapsed.Seconds, userActivity.ToString());
userActivities.Add(userActivity);
if (retryStatus.ContainsKey(UserProcess.SessionId))
retryStatus[UserProcess.SessionId] = 0;
else
retryStatus.Add(UserProcess.SessionId, 0);
userActivityTime.Reset();
}
catch (System.Net.Sockets.SocketException ex)
{
log.Error("Tray not running for sessionId " + UserProcess.SessionId + ". " + ex.Message);
if (retryStatus.ContainsKey(UserProcess.SessionId))
retryStatus[UserProcess.SessionId] = retryStatus[UserProcess.SessionId] + 1;
else
retryStatus.Add(UserProcess.SessionId, 1);
}
catch (Exception ex)
{
log.Error("Unable to connect to tray for sessionId " + UserProcess.SessionId + ". " + ex.Message);
if (retryStatus.ContainsKey(UserProcess.SessionId))
retryStatus[UserProcess.SessionId] = retryStatus[UserProcess.SessionId] + 1;
else
retryStatus.Add(UserProcess.SessionId, 1);
}
finally
{
remoteMethods = null;
}
return remoteMethods;
}