Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 473
  • Last Modified:

Remoting from server to client

Hi Experts,

Here is my remoting code:
->Interface
public interface IClient
      {
            void ReceiveMessage(string Data);
            
      }

      public interface IServer
      {
            void Subscribe(System.Collections.ArrayList Client);
            
      }

->Client
[Serializable]
      public class RemotingClient : MarshalByRefObject, RemotingManager.IClient
      {


            #region IClient Members

            public void ReceiveMessage(string Data)
            {
                  System.Diagnostics.Debug.WriteLine(Data);
                  
            }
            #endregion
      }

protected RemotingManager.IServer obj;

            private void button1_Click(object sender, EventArgs e)
            {
                  BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
                  serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
                  BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
                  System.Collections.Hashtable hashTable = new System.Collections.Hashtable();
                  hashTable.Add("port", 0);
                  HttpChannel ipcCh = new HttpChannel(hashTable, clientProvider, serverProvider);
                  ChannelServices.RegisterChannel(ipcCh);

                  obj =
                     (RemotingManager.IServer)Activator.GetObject
                     (typeof(RemotingManager.IServer),
                        textBox1.Text); // "http://localhost..."
                  }

private void button2_Click(object sender, EventArgs e)
            {
                  RemotingClient client=new RemotingClient();
                  System.Collections.ArrayList arraylist = new System.Collections.ArrayList();
                  arraylist.Add(client);
                  obj.Subscribe(arraylist);

            }

->Server
[Serializable]
public class RemotingServer : MarshalByRefObject, RemotingManager.IServer
{
      private ArrayList _clients = new ArrayList();

      public void Subscribe(System.Collections.ArrayList aClient)
      {
            RemotingManager.IClient Client = (RemotingManager.IClient)aClient[0];
            _clients.Add(Client);
            System.Diagnostics.Debug.WriteLine("Client added");
                Client.ReceiveMessage("Client added.");  // send message to the client
      }
}

protected void Button1_Click(object sender, EventArgs e)
      {
            StartServer();
            
      }

      HttpChannel ipcCh;
      
      protected void StartServer()
      {
            try
            {
                  BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
                  serverProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
                  BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
                  ipcCh = new HttpChannel(null, clientProvider, serverProvider);
                  if (ChannelServices.GetChannel(ipcCh.ToString()) == null)
                  ChannelServices.RegisterChannel(ipcCh);
                  WellKnownServiceTypeEntry entry=new WellKnownServiceTypeEntry(typeof(RemotingServer),
                                 "RemotingServer.rem",
                                 WellKnownObjectMode.SingleCall);
                  RemotingConfiguration.RegisterWellKnownServiceType(entry);
                  Response.Write("  Server started:"+ipcCh.ChannelName);
            }
            catch(Exception ex)
            {}
      }
      protected void Button2_Click(object sender, EventArgs e)
      {
                         I need to send a message to the client.
                        Something like this:
                        Client.SendMessage("My custom message");
                }

How can I send this message from the server to any client that subscribes my remote object ?

Thanks in advance for your answers.
0
noulouk
Asked:
noulouk
  • 3
  • 2
1 Solution
 
dunglaCommented:
Try this one

http://www.codeproject.com/csharp/RemotingAndEvents.asp

public void SendMessage(string message)
   {
      lock(_clients)
      {
         Console.WriteLine("\"{0}\" message will be sent to all clients.",
                                                                message);
         AsyncCallback asyncCallback = new AsyncCallback
            (OurAsyncCallbackHandler);

         foreach (DictionaryEntry entry in _clients)
         {
            // get the next receiver
            IChatClient iChatClient = (IChatClient) entry.Value;
            ReceiveMessageEventHandler remoteAsyncDelegate = new
               ReceiveMessageEventHandler(iChatClient.ReceiveMessage);

            // make up the cookies for the async callback
            AsyncCallBackData asyncCallBackData =
               new AsyncCallBackData();
            asyncCallBackData.RemoteAsyncDelegate =
               remoteAsyncDelegate;
            asyncCallBackData.MbrBeingCalled =
               (MarshalByRefObject) iChatClient;

            // and initiate the call
            IAsyncResult RemAr = remoteAsyncDelegate.BeginInvoke
               (message, asyncCallback, asyncCallBackData);
         }
      }  
   }

// Called by .NET <FONT style="BACKGROUND-COLOR: #b2b4bf" color=#000000>Remoting</FONT> when async call is finished.
   public static void OurAsyncCallbackHandler(IAsyncResult ar)
   {
      AsyncCallBackData asyncCallBackData = (AsyncCallBackData)
            ar.AsyncState;    

      try
      {
         object result =
             asyncCallBackData.RemoteAsyncDelegate.EndInvoke(ar);

         // the call is successfully finished and
         // we have call results here    
      }
      catch(Exception ex)
      {
         // The call has failed.
         // You can analyze an exception
         // to understand the reason.
         // I just exclude the failed receiver here.
         Console.WriteLine("Client call failed: {0}.", ex.Message);
         lock(_clients)
         {
            _clients.Remove( RemotingServices.GetObjectUri
               (asyncCallBackData.MbrBeingCalled) );
         }
      }
   }
0
 
nouloukAuthor Commented:
I know how to send the message from a client to other clients via the server. (Client1 -> Server -> Client2)
What I need is to send a message directly from the server to the client.(Server -> Client1 or Server -> Client2)

So, I want to be able to send a message to the client from the server in button2_click.
0
 
dunglaCommented:
this method will loop thru all client in hashtable then for each client, send message to client
public void SendMessage(string message)
   {
      lock(_clients)
      {
         Console.WriteLine("\"{0}\" message will be sent to all clients.",
                                                                message);
         AsyncCallback asyncCallback = new AsyncCallback
            (OurAsyncCallbackHandler);

         foreach (DictionaryEntry entry in _clients)
         {
            // get the next receiver
            IChatClient iChatClient = (IChatClient) entry.Value;
            ReceiveMessageEventHandler remoteAsyncDelegate = new
               ReceiveMessageEventHandler(iChatClient.ReceiveMessage);

            // make up the cookies for the async callback
            AsyncCallBackData asyncCallBackData =
               new AsyncCallBackData();
            asyncCallBackData.RemoteAsyncDelegate =
               remoteAsyncDelegate;
            asyncCallBackData.MbrBeingCalled =
               (MarshalByRefObject) iChatClient;

            // and initiate the call
            IAsyncResult RemAr = remoteAsyncDelegate.BeginInvoke
               (message, asyncCallback, asyncCallBackData);
         }
      }  
   }
0
 
nouloukAuthor Commented:
Ok I know.
That's why I send a message from 1 client to all others via the server.

But how can I access this method directly from the server (in sample code, the server access this method with Activator.GetObject, so the server is considered as client right!  This is the heart of my problem : the server is the server and not a client , that's why I think the server that creates remote objects and stores clients that subscribe can retrieve the process internally).

Hope I'm clear.
0
 
nouloukAuthor Commented:
Instead of using RemotingConfiguration.RegisterWellKnownServiceType, I use RemotingConfiguration.Marshall
Like this:
RemotingServer r=new RemotingServer();
ObjRef refl = RemotingServices.Marshal(r, "RemotingServer.rem");

Is there a way to do the same with RemotingConfiguration.RegisterWellKnownServiceType ? because all articles,samples use this function for their remote object.

I appreciate your help.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now