最近在我们的客户端环境之一中,我们观察到TCP Remoting服务到客户端通信需要8-10秒,但客户端到服务器的通信正在立即进行。接收到消息给客户端时的TCP Remoting延迟
首先,我将尝试解释我们正在尝试做什么。在我们的客户端环境中,每个服务器上有30-40个用户将登录,因此对于该用户,我们将启动托盘应用[客户端],并且在每个服务间隔期间,我们将向客户端发送请求以捕获当前用户活动窗口标题和进程名称一旦捕获,客户端将使用TCP Remoting将详细信息发回给我们的服务。
然后问题是40个用户完成一个活动需要7-8分钟的时间,所以我们认为使用属性MaxThreadLimit的线程轮询为3.我怀疑什么可能是服务延迟到客户端通信的原因。这里是我们正在使用的代码
public static List<DataEntity> GetAllUsersData()
{
/// This logic is implemented because on customer place as
/// more 40 user are logged in then capturing the useractivity is taking more than 5min
/// so we have implement the thread pool concept.
var complete = new CountdownEvent(1);
var throttle = new Semaphore(3, 3);
foreach (Process UserProcess in AllUsersProcess)
{
//Do not monitor the user activity if the user state is locked or personal mode or not authenticated.
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();
}
这是我们将对所有客户端进行tcp远程调用的方法。
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);
//To avoid data drop when multiple users of system running in different timezone.
userActivity.ActivityTime = DateTime.Now;
userActivity.Offline = ProbeOffline;
//Fix for some applications which are running in elevated mode
//and not able to detect the process names. Those are handled
//here.
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;
}
首先检查您的网络。尝试从服务器ping一个客户端,并检查需要多长时间。你在使用主机名或IP地址吗? – Caesar