CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Feb 2005
    Location
    Israel
    Posts
    1,475

    Selective events

    I have a server with clients. The clients each get a unique Id from the server. Each client knows about the other connected clients Ids.
    I want the client to raise an event in other clients. I don't want all the clients to receive the events, but only selected ones.

    A simple example: I have a chat program. There are 100 clients, each is involved in a chat with exactly one other clients (50 pairs). When a client want to send a message it raises an event on the server, and only the client in the chat receive this message.

    By raising an event normally all clients will need to check if the event is relevant for them. I don't want the event to be raised in the first place, and I only ant to add the code to the server and not in the listening client.

    How to do that? Any suggestions?

  2. #2
    Join Date
    Jun 2004
    Location
    New Jersey, USA
    Posts
    341

    Re: Selective events

    You can have server controll what cleints receive event. I guess you can try to use ManualResetEvent if you are using cleints on different threads. Just a guess of mine. I am not sure how cleints communicate with the server in your case but if it is clioent server, just send messages to only selected cleints that is controlled by server
    "We act as though comfort and luxury were the chief requirements of
    life, when all that we need to make us happy is something to be
    enthusiastic about."

    - Einstein

  3. #3
    Join Date
    Feb 2005
    Location
    Israel
    Posts
    1,475

    Re: Selective events

    But we are talking about events, not just regular messages. Each client register for the event, but if the server needs it invokes the event only in certain clients. This effect I don't know how to acheive.

  4. #4
    Join Date
    Sep 1999
    Location
    Madurai , TamilNadu , INDIA
    Posts
    1,024

    Re: Selective events

    What is the condition to invoke only certain/selected clients?

  5. #5
    Join Date
    Feb 2005
    Location
    Israel
    Posts
    1,475

    Re: Selective events

    Does it really matter? If so, then a possible scenario is to let the client pass the IDs of clients it wants to raise event in to the server, and server will invoke the event selectively. Lets assume that each client and of course the server has the unique ID of other clients. (The ID type is not important - but it is unique for each client).
    How does the selective event can be done?

  6. #6
    Join Date
    Sep 1999
    Location
    Madurai , TamilNadu , INDIA
    Posts
    1,024

    Re: Selective events

    AFAIK, .NET does not support selective event raising. Only workaround I can think of is, let the server register an event handler in all clients. Clients raise this event with client ids as event args. Then server event handler dynamically add clients to the actual event and raise the event.

    Something like the following:

    Code:
    private void Server_ListenForClient(Object sender, ServerEventArg e)
    {
                    if (eventArg.EventType == SomeEvent)
                    { 
                             // use the client ids to retrieve the client object. add all event handler like this
    	         this.SomeEvent += new SomeEventHandler(clientObject.SomeEventHandler);
    
    	// raise the event
                    }
                    else if (<Some Other event code>)
                    {
    
                    }
    
    	// flow will return here after all the event handlers are done.
    
    	// remove the events handlers you added just above. 
    }
    
    public SomeServerMethod(client c, EventType someInterestedEvent)
    {
        ......
    }
    
    
    // Event arg class.
    public class ServerEventArg
    {
          private EventType eventToBeRaisedType;    << Event Type is an enum
          private int[] clientIDs;
    
         ..............................
    
    }
    I know this looks very dirty but that is the only workaround I can think of

    [Updated] You could add a public method in Server class that could be called from the client instead of raising an event to the server.
    Last edited by poochi; October 7th, 2005 at 09:29 AM.

  7. #7
    Join Date
    Sep 1999
    Location
    Madurai , TamilNadu , INDIA
    Posts
    1,024

    Re: Selective events

    ok. It seems possible with straight forward way if we learn how to use Delegate.GetInvocationList() method. Please use Reflection decompiler and see how it invokes a method in your client class. Check the MulticastDelegate and Delegate classes (Delegate.Method, Delegate.Target are the one we need to be looking to).

  8. #8
    Join Date
    Feb 2005
    Location
    Israel
    Posts
    1,475

    Re: Selective events

    Quote Originally Posted by poochi
    You could add a public method in Server class that could be called from the client instead of raising an event to the server
    That's exactly what I am doing.

    Quote Originally Posted by poochi
    It seems possible with straight forward way if we learn how to use Delegate.GetInvocationList() method. Please use Reflection decompiler and see how it invokes a method in your client class. Check the MulticastDelegate and Delegate classes (Delegate.Method, Delegate.Target are the one we need to be looking to).
    Thats the direction I thought of. The problem is I could not find even one good resource which will tell me how to use GetInvocationList method in order to check which client belongs the event.
    I thought maybe to map the client ID with the event handlers, but I don't know what to map, and when is the mapping should be done.

  9. #9
    Join Date
    Sep 1999
    Location
    Madurai , TamilNadu , INDIA
    Posts
    1,024

    Re: Selective events

    OK here is the sample. It selectively sends event to the clients. It does not have any comment . So, if you have any question, please feel free to post it here. This code compiles and runs fine. You can improve the server method to invoke any delegate.

    Code:
        class Client
        {
            private int clientID = -1;
    
            public Client(int clientID)
            {
                this.clientID = clientID;
            }
    
            public int ClientID
            {
                get { return clientID; }
                set { clientID = value; }
            }
    
            public void MyTestEventHandler(object sender, TestEventArgs eventArgs)
            {
                System.Console.WriteLine("Client " + clientID.ToString() + " is called");
            }
    
            static void Main(string[] args)
            {
                // create server object
                Server server = new Server();
    
                // create client objects. 
                Client c1 = new Client(1);
                Client c2 = new Client(2);
    
                // clients adds event handler to the events they are interested in. 
                server.SelectiveEvent += new MyTestEvent(c1.MyTestEventHandler);
                server.SelectiveEvent += new MyTestEvent(c2.MyTestEventHandler);
    
                // call server method to selectively invoke the clients
                server.InvokeClients(new int[] { 2 }, new TestEventArgs());
            }
        }
    
        public class Server
        {
            public event MyTestEvent SelectiveEvent;
    
            public void InvokeClients(int[] clientIDs, TestEventArgs args)
            {
                if ((clientIDs != null) && (clientIDs.Length > 0))
                {
                    foreach (MyTestEvent eventDelegate in SelectiveEvent.GetInvocationList())
                    {
                        Client targetObject = eventDelegate.Target as Client;
    
                        // loop thro' the array and see whether the client is in the id list.
                        // there are better way to do it if you don't want to loop for every client.
                        // this will give you an idea.
                        for (int index = 0; index < clientIDs.Length; index++)
                        {
                            if (targetObject.ClientID == clientIDs[index])
                            {
                                eventDelegate(this, args);
                                break;
                            }
                        }
                    }
                }
            }
        }
    
    
        /// <summary>
        /// TestEventArgs 
        /// </summary>
        public class TestEventArgs : EventArgs
        {
            // Some Event args here. 
        }
    
        /// <summary>
        /// Delegate declaration
        /// </summary>
        public delegate void MyTestEvent(object sender, TestEventArgs eventArgs);

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured