منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب
سؤال بخصوص المستخدمين النشطاء الحاليين علي الشبكة - نسخة قابلة للطباعة

+- منتدى فيجوال بيسك لكل العرب | منتدى المبرمجين العرب (http://vb4arb.com/vb)
+-- قسم : قسم لغة الفيجوال بيسك VB.NET (http://vb4arb.com/vb/forumdisplay.php?fid=182)
+--- قسم : قسم اسئلة VB.NET (http://vb4arb.com/vb/forumdisplay.php?fid=183)
+--- الموضوع : سؤال بخصوص المستخدمين النشطاء الحاليين علي الشبكة (/showthread.php?tid=45757)



سؤال بخصوص المستخدمين النشطاء الحاليين علي الشبكة - عبدالكريم برشدان - 23-03-23

اهلا بيكم اعزائي 

يوجد لدي جدول باسم المستخدمين وبه حقل حالة المستخدم واعمل علي جزائية المستخدمين النشطاء الحاليين علي البرنامج الان البرنامج مربوطة علي شبكة داخلية 

انا استخدم timer في قراءة بيانات حالات المستخدمين في الجدول ولكن تواجهني مشكلة بيسطة وهي حركة timer واضحة عند المستخدم وانا اريد الفكرة مثل الماسنجر 

اذا دخل المستخدم يظهر في القائمة واذا خرج  يختفي من القائمة والا اريد حركة التايمر توضخ عند المستخدم

وهل يوجد حل اسهل وبديل للفكرة


RE: سؤال بخصوص المستخدمين النشطاء الحاليين علي الشبكة - sanyor77 - 27-03-23

للحفاظ على أداء البرنامج وعدم إظهار حركة التايمر للمستخدم، يمكنك البحث عن تحسين كفاءة الكود وتقليل التحديثات المتكررة لواجهة المستخدم.
في المثال الذي طرحته، يمكنك إجراء التحديثات على قائمة المستخدمين النشطين بدلاً من تحديث القائمة بأكملها. يمكنك استخدام مفتاح فريد لكل مستخدم (مثل المعرّف) للتعرف على المستخدمين الجدد أو المستخدمين الذين قد غادروا.
أولاً، يمكنك تحسين التحديثات بواسطة تحديد تغييرات الحالة فقط. عند استلام بيانات المستخدمين الجديدة، قارنها بالبيانات الحالية وقم بتحديث القائمة فقط إذا كان هناك تغيير في حالة المستخدم (مثل: تسجيل الدخول أو الخروج).
ثانيًا، يمكنك استخدام تقنيات مثل "SignalR" لتنفيذ تحديثات الواجهة المستخدم في الوقت الفعلي بدون الحاجة إلى استخدام تايمر. تعتمد تقنية SignalR على تقنيات الاتصال الحديثة مثل WebSockets لتمكين اتصال ثنائي الاتجاه بين العميل والخادم. بذلك يمكن للخادم إرسال تحديثات الحالة إلى العملاء عند حدوثها بدون الحاجة إلى الاستعلام المتكرر.
للبدء باستخدام SignalR، يمكنك الرجوع إلى التوجيهات الرسمية في الرابط التالي: https://docs.microsoft.com/en-us/aspnet/signalr/overview/getting-started/introduction-to-signalr
من خلال استخدام هذه التقنيات وتحسين الكفاءة، سيصبح برنامجك أكثر استجابة ولن يظهر التأثير الناتج عن استخدام التايمر للمستخدمين.
 



نعم، يوجد حل بديل أكثر بساطة باستخدام تكنولوجيا البولنغ (Polling)، وهو عبارة عن عمل استعلام دوري للخادم لجلب تحديثات البيانات. يمكنك تطبيق هذه الفكرة بسهولة باستخدام تايمر في البرنامج، لكن يجب مراعاة تحسين الأداء لتجنب التأثير على المستخدم.
الخطوات التالية توضح كيفية تطبيق هذا الحل:
  1. قم بإنشاء دالة لجلب بيانات المستخدمين النشطين من الخادم.
  2. قم بتحديد فترة زمنية مناسبة لتنفيذ التايمر (مثل كل 30 ثانية أو 1 دقيقة) وتجنب فترات زمنية قصيرة جدًا للتقليل من الاستعلامات المتكررة.
  3. استخدم التايمر لتنفيذ الدالة التي تجلب بيانات المستخدمين النشطين دوريًا.
  4. قارن بيانات المستخدمين النشطين الجديدة بالبيانات الحالية وقم بتحديث القائمة فقط إذا كان هناك تغيير في حالة المستخدم (مثل تسجيل الدخول أو الخروج).
  5. لتقليل التأثير على المستخدم، قد يكون من الأفضل تنفيذ هذه العملية في خيط ثانوي (Background Worker) لتجنب تجميد واجهة المستخدم أثناء استعلام الخادم.
يجب العلم أن هذا الحل ليس بديهيًا ولا يوفر تحديثات في الوقت الفعلي كتقنية SignalR التي ذكرتها سابقًا. ومع ذلك، يعتبر هذا الحل أكثر بساطة في التنفيذ وقد يكون مناسبًا لمتطلبات معينة.
يرجى مراعاة أن تحديث القائمة فقط عند وجود تغيير في حالة المستخدمين النشطين سيساعد في تحسين الأداء وتجنب حرك
 


بالطبع، يمكنني توفير مثال بسيط لكيفية تنفيذ هذا الحل باستخدام تايمر وخيط ثانوي في تطبيق Windows Forms بلغة VB.NET:
  1. قم بإنشاء دالة لجلب بيانات المستخدمين النشطين:
 

PHP كود :
Private Function GetActiveUsers() As List(Of String)
 
   ' استبدل هذا الكود بكود لجلب بيانات المستخدمين النشطين من قاعدة البيانات
    Dim activeUsers As New List(Of String)
    activeUsers.Add("User1")
    activeUsers.Add("User2")
    Return activeUsers
End Function 


قم بإنشاء دالة لتحديث قائمة المستخدمين النشطين على الواجهة:

PHP كود :
Delegate Sub UpdateActiveUsersDelegate(ByVal activeUsers As List(Of String))

Private 
Sub UpdateActiveUsers(ByVal activeUsers As List(Of String))
 
   If Me.InvokeRequired Then
        Dim d 
As New UpdateActiveUsersDelegate(AddressOf UpdateActiveUsers)
 
       Me.Invoke(d, New Object() {activeUsers})
 
   Else
        
' استبدل هذا الكود بكود تحديث قائمة المستخدمين النشطين على الواجهة
        ListBox1.Items.Clear()
        ListBox1.Items.AddRange(activeUsers.ToArray())
    End If
End Sub 


قم بإنشاء دالة لتنفيذ الاستعلام دوريًا باستخدام تايمر:


PHP كود :
Private Sub Timer1_Tick(sender As ObjectAs EventArgsHandles Timer1.Tick
    Dim bw 
As New System.ComponentModel.BackgroundWorker()
 
   AddHandler bw.DoWorkAddressOf bw_DoWork
    AddHandler bw
.RunWorkerCompletedAddressOf bw_RunWorkerCompleted
    bw
.RunWorkerAsync()
End Sub

Private Sub bw_DoWork(sender As ObjectAs System.ComponentModel.DoWorkEventArgs)
 
   Dim activeUsers As List(Of String) = GetActiveUsers()
 
   e.Result activeUsers
End Sub

Private Sub bw_RunWorkerCompleted(sender As ObjectAs System.ComponentModel.RunWorkerCompletedEventArgs)
 
   Dim activeUsers As List(Of String) = CType(e.Result, List(Of String))
 
   UpdateActiveUsers(activeUsers)
End Sub 



قم بتعيين فترة زمنية مناسبة لتنفيذ التايمر:

PHP كود :
Private Sub Form1_Load(sender As ObjectAs EventArgsHandles MyBase.Load
    Timer1
.Interval 30000 ' تنفيذ التايمر كل 30 ثانية
    Timer1.Start()
End Sub 

هذا المثال البسيط يوضح كيفية استخدام تايمر لتنفيذ استعلام دوري لجلب بيانات المستخدمين النشطين وتحديث قائمة المستخدمين على الواجهة. 

يمكنك استخدام الكود المذكور أعلاه كنقطة انطلاق لتنفيذ الحل المطلوب. لتحسين الأداء وتجنب تحديث القائمة بشكل متكرر، يمكنك مقارنة بيانات المستخدمين النشطين الجديدة بالبيانات الحالية وتحديث القائمة فقط إذا كان هناك تغيير في حالة المستخدم.
لفعل ذلك، يمكنك تعديل دالة bw_RunWorkerCompleted بحيث تتحقق أولاً مما إذا كانت البيانات الجديدة مختلفة عن البيانات الحالية قبل تحديث القائمة:



PHP كود :
Private Sub bw_RunWorkerCompleted(sender As ObjectAs System.ComponentModel.RunWorkerCompletedEventArgs)
 
   Dim newActiveUsers As List(Of String) = CType(e.Result, List(Of String))

 
   ' قارن بيانات المستخدمين النشطين الجديدة بالبيانات الحالية
    Dim isDataChanged As Boolean = False
    If ListBox1.Items.Count <> newActiveUsers.Count Then
        isDataChanged = True
    Else
        For i As Integer = 0 To ListBox1.Items.Count - 1
            If ListBox1.Items(i).ToString() <> newActiveUsers(i) Then
                isDataChanged = True
                Exit For
            End If
        Next
    End If

    ' 
إذا كان هناك تغيير في بيانات المستخدمين النشطين، قم بتحديث القائمة
    If isDataChanged Then
        UpdateActiveUsers
(newActiveUsers)
 
   End If
End Sub 




باستخدام هذا الكود، ستتم مقارنة بيانات المستخدمين النشطين الجديدة بالبيانات الحالية وسيتم تحديث قائمة المستخدمين على الواجهة فقط إذا كان هناك تغيير في حالة المستخدم (مثل تسجيل الدخول أو الخروج). هذا يساعد في تحسين الأداء وتجنب التحديثات المتكررة للقائمة.