最近在我們的客戶端環境之一中,我們觀察到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