Avatar billede knaldeglad Nybegynder
31. juli 2006 - 09:46 Der er 18 kommentarer og
1 løsning

Eksempel på remoting i.net 2.0, findes det ?

Hej.. sidder og fedter med at få noget remoting op og køre på .net 2.0...  fatter ik at det ik virker..  og ikke mindst at jeg ikke kan finde et godt fungerende eksempel.
Avatar billede dr_chaos Nybegynder
31. juli 2006 - 09:51 #1
Avatar billede knaldeglad Nybegynder
31. juli 2006 - 10:35 #2
er de ike lidt spinkle... hvad med sincprovider, Ipc ... det er der ikke...  ligner mest af alt noget der kun virker på 1.1  eller er jeg way off.....  har testet nogle simple remoting ting fra 1.1 ,de virker bare ikke i 2.0....  sikkerhed dit og dat....  suk..
Avatar billede knaldeglad Nybegynder
31. juli 2006 - 11:07 #3
ok.. her kommer lige noget kode...  evt en kan se hvad der er galt....
der kommer en exception på klientet.
  Message="Cannot load type 'Test.EVSMiniServerInterface, EVSTestRemotingClient, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'."
  Source="mscorlib"

klientkode:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;

namespace Test
{
    class EVSTestClient
    {
        static void Main(string[] args)
        {
            IpcChannel ipc = new IpcChannel("MessageClient");
            ChannelServices.RegisterChannel(ipc, true);
            EVSMiniServerInterface sm = (EVSMiniServerInterface)Activator.GetObject(typeof(Visiolog.EVSMiniServerInterface), "ipc://MessageServer/MessageServer.rem");
            if (sm == null)
            {
                Console.WriteLine("Failed to communicate with remote server.");
                return;
            }

            Console.WriteLine("Enter message to send to server:");
            string message = Console.ReadLine();
            Console.WriteLine("Enter your name (sender):");
            string sender = Console.ReadLine();
            sm.ChangeGooditems(message, sender); 
        }
    }
}

Interface:
using System;
using System.Collections.Generic;
using System.Text;

namespace Test
{
    interface EVSMiniServerInterface
    {
        void ChangeGooditems(string message, string sender);
    }
}

Serverkode:

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Drawing;
using System.ComponentModel;
using System.Runtime.Remoting;
using System.Windows.Forms;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using System.Threading;

namespace Test
{
    class EVSRemotingMiniServer
    {
        private EVSRemotingImplementation eri;
        private delegate void ShowMessageDelegate(string message, string sender);
        private ShowMessageDelegate showMessage;

        public Thread myMiniRemotingServerThread;

        public EVSRemotingMiniServer()
        {
            startRemotingService();
        }

        public void startRemotingService()
        {
            myMiniRemotingServerThread = new Thread(new System.Threading.ThreadStart(this.remotingService));
            myMiniRemotingServerThread.Name = "myMiniRemotingServerThread";
            myMiniRemotingServerThread.Start();
        }

        private void remotingService()
        {
            System.Threading.Thread.Sleep(10);
            BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider();
            serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
            BinaryClientFormatterSinkProvider clientProv = new BinaryClientFormatterSinkProvider();

            System.Collections.Hashtable properties = new System.Collections.Hashtable();
            properties["portName"] = "MessageServer";
            IpcChannel ipc = new IpcChannel(properties, clientProv, serverProv);
            ChannelServices.RegisterChannel(ipc,true);
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(EVSRemotingImplementation), "MessageServer.rem", WellKnownObjectMode.Singleton);

            //eri = (EVSRemotingImplementation)Activator.GetObject(typeof(EVSRemotingImplementation), "ipc://MessageServer/MessageServer.rem");
           
            //showMessage = new ShowMessageDelegate(ShowReceivedMessage);
           
            //eri.OnMessageReceived += new OnMessageReceivedDelegate(eri_OnMessageReceived);

        }

        public void eri_OnMessageReceived(string message, string sender)
        {
            //this.Invoke(showMessage, new object[] { message, sender });
            Console.WriteLine(message);
        }

        public void ShowReceivedMessage(string message, string sender)
        {
            Console.WriteLine(message+sender);
        }
    }
}

Implementation af remote funktion:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;

namespace Test
{
    public delegate void OnMessageReceivedDelegate(string message, string sender);
    [Serializable]
    public class EVSRemotingImplementation:MarshalByRefObject,EVSMiniServerInterface
    {
        public event OnMessageReceivedDelegate OnMessageReceived;
        public EVSRemotingImplementation()
        {}

        public void ChangeGooditems(string message, string sender)
        {
            if ((OnMessageReceived != null)&&(OnMessageReceived.GetInvocationList().Length > 0))
                OnMessageReceived(message, sender);
        }
    }
}
Avatar billede md_craig Nybegynder
31. juli 2006 - 11:09 #4
Jeg har ellers noget .NET 1.1 der er konverteret til .NET 2.0 som virker uden probs, hvor jeg bruger Providers og Sponsors...

Server opstart:
ListDictionary channelProperties = new ListDictionary();
channelProperties.Add("port", port);

HttpChannel chn = new HttpChannel(channelProperties, Providers.Instance.BinaryClientProvider, Providers.Instance.BinaryServerProvider);
            ChannelServices.RegisterChannel(chn);
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(ServerCom), "ServerCom.rem", WellKnownObjectMode.SingleCall);

Providers til både Server og Client:
    public class Providers
    {
        private BinaryServerFormatterSinkProvider binSP = new BinaryServerFormatterSinkProvider();
        private BinaryClientFormatterSinkProvider binCP = new BinaryClientFormatterSinkProvider();

        private static Providers instance = new Providers();
        private Providers()
        {
            binSP.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
        }
        public static Providers Instance { get{ return instance;} }

        public BinaryServerFormatterSinkProvider BinaryServerProvider { get{return binSP;}}
        public BinaryClientFormatterSinkProvider BinaryClientProvider { get{return binCP;}}
    }

Klasse der håndtereed Asynkron levering til klienter:

    public class SubscriberCaller
    {
        public SubscriberCaller()
        {}

        #region - Unnified Network Transportation -
        public delegate object DeliverObjectHandler( object obj, string type );
        public void deliverObject( object obj, string type, ArrayList recievers )
        {
            AsyncCallback asyncCallback = new AsyncCallback(OurAsyncCallbackHandler);
            foreach (Subscriber sub in recievers)
            {
                Console.WriteLine("Delivereing object to Client of type: {0}.", type);

                ISubscriberCom objReciever = sub.RemoteSubscriber;
                DeliverObjectHandler remoteAsyncDeletage = new DeliverObjectHandler(objReciever.recieveObject);

                AsyncCallBackData acbData = new AsyncCallBackData();
                acbData.RemoteAsyncDelegate = remoteAsyncDeletage;
                acbData.subscriberBeingCalled = sub;

                IAsyncResult asyncRes = remoteAsyncDeletage.BeginInvoke(obj, type, asyncCallback, acbData);
            }
        }

        private class AsyncCallBackData
        {
            public DeliverObjectHandler RemoteAsyncDelegate;
            public Subscriber subscriberBeingCalled;
        }

        public static void OurAsyncCallbackHandler(IAsyncResult ar)
        {
            AsyncCallBackData asbData = (AsyncCallBackData) ar.AsyncState;

            try
            {
                object result = asbData.RemoteAsyncDelegate.EndInvoke(ar);
            }
            catch(Exception ex)
            {
                //TODO: Enter in log instead
                //REMOVE: Console.WriteLine
                Console.WriteLine("Client call failed: {0}. Client will be removed from list.", ex.Message);
                //Console.WriteLine("Stacktrace: \r {0}", ex.StackTrace);
                ComHandler.Instance.detachSubscriber(asbData.subscriberBeingCalled.SubscriberID);
            }
        }
        #endregion

    }

Klient opstart:
                ListDictionary channelProperties = new ListDictionary();
                channelProperties.Add("port", int.Parse(ClientState.Instance.Port));

                HttpChannel chn = new HttpChannel(channelProperties, Providers.Instance.BinaryClientProvider, Providers.Instance.BinaryServerProvider);
                ChannelServices.RegisterChannel(chn);

                SubscriberCom subCom = new SubscriberCom();

                //com = (IServerCom) Activator.GetObject(typeof(IServerCom), address + "/ServerCom.rem");
                com = (IServerCom) RemotingServices.Connect(typeof(IServerCom), address+"/ServerCom.rem");
                ClientState.Instance.ClientID = (string) com.attachSubscriber(subCom, ClientState.Instance.ClientName);

                ILease lease = (ILease) RemotingServices.GetLifetimeService(subCom);
                lease.Register((ISponsor) new SubscriberSponsor());

og Sponsor:
    public class SubscriberSponsor : MarshalByRefObject, ISponsor
    {
        public SubscriberSponsor()
        {}

        #region ISponsor Members
        public TimeSpan Renewal(ILease lease)
        {
            // TODO:  Add SubscriberSponsor.Renewal implementation
            return TimeSpan.FromMinutes(10);
        }
        #endregion
    }

--------------------------------------------------------------------------------------

Tror stort set det var det....
Det er ikke super smukt eller godt kode...

Men er også fra mine tidlige dage i .NET... Men det virker fint for mig i .NET 2.0 også....
Avatar billede md_craig Nybegynder
31. juli 2006 - 11:25 #5
Skal lige siges at jeg bruger Http channels... har også prøvet TCP channels... virkede også fint... men ikke IPC channels...
Avatar billede md_craig Nybegynder
31. juli 2006 - 11:34 #6
hmmm... det ligner at du prøver at benytte IPC til at kommunikere med en anden computer??...

:: ipc://MessageServer/MessageServer.rem

IPC er jo Interprocess Communication... så den er til kommunikation mellem 2 processer / applicationer på en computer og ikke til over Netværk

fra dokumentationen:
The IpcServerChannel class uses the Windows interprocess communication (IPC) system to transport messages between application domains on the same computer. When communicating between application domains on the same computer, the IPC channel is much faster than the TCP or HTTP channels.

Så er du sikker på du har fat i den rigtige type protokol?
Avatar billede knaldeglad Nybegynder
31. juli 2006 - 11:40 #7
nej, det er jeg da ikke.......  hm...  nu er det så på samme PC jeg arbejder men det skal da ændres....
Avatar billede md_craig Nybegynder
31. juli 2006 - 11:42 #8
Never mind... Mig der tåger lidt der....
Er naturligvis PortName'et du bruger...

Bare mig der plejer at bruge de andre constructors....
Men det er til InterProcess ??
Avatar billede knaldeglad Nybegynder
31. juli 2006 - 12:03 #9
hm...  har ændret det til tcp... men server nægter aktivt, siger klient exception....
Avatar billede md_craig Nybegynder
31. juli 2006 - 12:44 #10
du skal ændre et par andre ting også...
Det skal ikke længere hede "portName" men bare port...

Hvis du vil benytte CallBacks (Server der kalder klienten)... så skal du registrere en port hos klienten også... En anden port end den din server har...

-------------------------------------------------------------------------------------

        private void remotingService()
        {
            BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider();
            BinaryClientFormatterSinkProvider clientProv = new BinaryClientFormatterSinkProvider();
            serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

            System.Collections.Hashtable properties = new System.Collections.Hashtable();
            properties["port"] = 8088;

            TcpChannel tcp = new TcpChannel(properties, clientProv, serverProv);
            ChannelServices.RegisterChannel(ipc, false); //Prøv at starte med at få det til at virke med false
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(EVSRemotingImplementation), "MessageServer.rem", WellKnownObjectMode.SingleCall);
            //SingleCall anbefales gennerelt, normal gør jeg det at jeg bruger single calls, og gemmer min singleton inde bag et interface.. så slipper du for en masse bøvl på serversiden
            //Bøvlen er naturligvis at der skal til at være sponsors og alt muligt på serversiden, ting som gennerelt set i mine øjne er overføldigt for en server implementation
        }
-------------------------------------------------------------------------------------

Ang det med singlecall er her det roughly gjort som jeg plejer at gøre istedet:
Sagen er at en Singleton der oprettes Remote kræver leaces osv da den ellers dør efter en given tid og altså ikke først når serveren lukkes ned... en helt alm. singleton vil eksistere så længe serveren kører...

derfor plejer jeg at ligge et interface der gennerelt bare sørger for at kaste videre, det kan sagtens gøre lidt andre ting også, så længe man bare ikke begynder at lagre "states" i det... fx en state om hvor mange gange givne klienter har lavet et kald kunne være en "state" man have lyst til at gemme... eller om Klienter må lave kald osv osv... Man kan naturligvis godt bruge SingleTon modellen på samme måde, og man kan også bruge den til states, men så skal man tænke sig om...

-------------------------------------------------------------------------------------
    public delegate void OnMessageReceivedDelegate(string message, string sender);
    [Serializable]
    public class EVSRemotingImplementation:MarshalByRefObject,EVSMiniServerInterface
    {
        public void ChangeGooditems(string message, string sender)
        {
                    EVSRemotingInnerSingleton.Instance.ChangeGooditems(message, sender);
        }
    }
        public class EVSRemotingInnerSingleton
        {
            private static EVSRemotingInnerSingleton instance = new EVSRemotingInnerSingleton();
            public static EVSRemotingInnerSingleton Instance { get { return instance; } }
            private EVSRemotingInnerSingleton()
            { }

            public event OnMessageReceivedDelegate OnMessageReceived;
            public void ChangeGooditems(string message, string sender)
            {
                if ((OnMessageReceived != null) && (OnMessageReceived.GetInvocationList().Length > 0))
                    OnMessageReceived(message, sender);
            }
        }
-------------------------------------------------------------------------------------

Sidst sagt, så syns jeg ikke jeg kan se nogen klient i den kode du har postet?
Avatar billede md_craig Nybegynder
31. juli 2006 - 12:48 #11
Meh... jeg tåger pænt meget i dag kan jeg se... jeg kigger lige på klienten også :P
Avatar billede md_craig Nybegynder
31. juli 2006 - 12:53 #12
namespace Test
{
    class EVSTestClient
    {
        static void Main(string[] args)
        {
            BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider();
            serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;
            BinaryClientFormatterSinkProvider clientProv = new BinaryClientFormatterSinkProvider();

            System.Collections.Hashtable properties = new System.Collections.Hashtable();
            properties["port"] = 9000;

            TcpChannel tcp = new TcpChannel(channelProperties, clientProv, serverProv);
            ChannelServices.RegisterChannel(tcp, false); //Igen, prøv at få det til at kører med false først
            EVSMiniServerInterface sm = (EVSMiniServerInterface)Activator.GetObject(typeof(Visiolog.EVSMiniServerInterface), "tcp://localhost:8088/MessageServer.rem");
            if (sm == null)
            {
                Console.WriteLine("Failed to communicate with remote server.");
                return;
            }

            Console.WriteLine("Enter message to send to server:");
            string message = Console.ReadLine();
            Console.WriteLine("Enter your name (sender):");
            string sender = Console.ReadLine();
            sm.ChangeGooditems(message, sender); 
        }
    }
}

namespace Test
{
    interface EVSMiniServerInterface
    {
        void ChangeGooditems(string message, string sender);
    }
}
Avatar billede md_craig Nybegynder
31. juli 2006 - 12:54 #13
Det er sådan rettet til "AdHoc" så det er ingen garanti... men skulle give nogle af de punkter der måske er galt med... men ellers må du jo poste din kode efter at have rettet det til TCP channels...
Avatar billede knaldeglad Nybegynder
31. juli 2006 - 13:17 #14
lol tak...  kiger lige lidt på det.
Avatar billede knaldeglad Nybegynder
31. juli 2006 - 14:16 #15
øv... tilage ved fejlen jeg nævnte i toppen.. "cannot load type"  kommer der hvor jeg kalder remote funktionen....
Avatar billede knaldeglad Nybegynder
31. juli 2006 - 14:17 #16
bruger det kode du har postet... dvs mit, med dine ændringer... :O)
Avatar billede md_craig Nybegynder
31. juli 2006 - 15:42 #17
Ok her er hele koden.... det virker hvertfald for mig...
Jeg har lavet 3 projekter...:

RemotingServer: (Har RemotingInterface som referance)
----------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.ComponentModel;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Threading;

using RemotingClient;
using RemotingInterfaces;


namespace RemotingServer
{
    class Program
    {
        static void Main(string[] args)
        {
            EVSRemotingInnerSingleton.Instance.OnMessageReceived += new OnMessageReceivedDelegate(Instance_OnMessageReceived);

            EVSRemotingMiniServer server = new EVSRemotingMiniServer();

            Console.WriteLine("Type Eny Key to Shutdown the server");
            Console.ReadLine();
            Environment.Exit(0);
        }

        static void Instance_OnMessageReceived(string message, string sender)
        {
            Console.WriteLine("Message: \n\r {0} \n\r\n\r Sender: \n\r {1} \n\r\n\r --------------- \n\r", message, sender);
        }
    }

    class EVSRemotingMiniServer
    {
        private EVSRemotingImplementation eri;
        private delegate void ShowMessageDelegate(string message, string sender);
        private ShowMessageDelegate showMessage;

        public Thread myMiniRemotingServerThread;

        public EVSRemotingMiniServer()
        {
            this.startRemotingService();
        }

        public void startRemotingService()
        {
            myMiniRemotingServerThread = new Thread(new System.Threading.ThreadStart(this.remotingService));
            myMiniRemotingServerThread.Start();
        }

        private void remotingService()
        {
            BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider();
            BinaryClientFormatterSinkProvider clientProv = new BinaryClientFormatterSinkProvider();
            serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

            System.Collections.Hashtable properties = new System.Collections.Hashtable();
            properties["port"] = 9900;

            try
            {
                TcpChannel tcp = new TcpChannel(properties, clientProv, serverProv);
                ChannelServices.RegisterChannel(tcp, false);
                RemotingConfiguration.RegisterWellKnownServiceType(typeof(EVSRemotingImplementation), "MessageServer.rem", WellKnownObjectMode.SingleCall);

                Console.WriteLine("TcpRemoting Server Started");
            }
            catch (Exception ex)
            {
                Console.WriteLine("------------------------------------------------------------------------");
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
                Console.WriteLine();
            }

            //SingleCall anbefales gennerelt, normal gør jeg det at jeg bruger single calls, og gemmer min singleton inde bag et interface.. så slipper du for en masse bøvl på serversiden
            //Bøvlen er naturligvis at der skal til at være sponsors og alt muligt på serversiden, ting som gennerelt set i mine øjne er overføldigt for en server implementation
        }

        public void eri_OnMessageReceived(string message, string sender)
        {
            //this.Invoke(showMessage, new object[] { message, sender });
            Console.WriteLine(message);
        }

        public void ShowReceivedMessage(string message, string sender)
        {
            Console.WriteLine(message + sender);
        }
    }

    public delegate void OnMessageReceivedDelegate(string message, string sender);

    [Serializable]
    public class EVSRemotingImplementation : MarshalByRefObject, EVSMiniServerInterface
    {
        public void ChangeGooditems(string message, string sender)
        {
            EVSRemotingInnerSingleton.Instance.ChangeGooditems(message, sender);
        }
    }

    public class EVSRemotingInnerSingleton
    {
        private static EVSRemotingInnerSingleton instance = new EVSRemotingInnerSingleton();
        public static EVSRemotingInnerSingleton Instance { get { return instance; } }
        private EVSRemotingInnerSingleton()
        { }

        public event OnMessageReceivedDelegate OnMessageReceived;
        public void ChangeGooditems(string message, string sender)
        {
            if ((OnMessageReceived != null) && (OnMessageReceived.GetInvocationList().Length > 0))
                OnMessageReceived(message, sender);
        }
    }
}

----------------------------------------------------------------------------------------


RemotingInterface:
----------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

namespace RemotingInterfaces
{
    public interface EVSMiniServerInterface
    {
        void ChangeGooditems(string message, string sender);
    }
}

----------------------------------------------------------------------------------------


RemotingClient: (Har RemotingInterface som referance)
----------------------------------------------------------------------------------------

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;

namespace RemotingClient
{
    class Program
    {
        static void Main(string[] args)
        {
            BinaryServerFormatterSinkProvider serverProv = new BinaryServerFormatterSinkProvider();
            BinaryClientFormatterSinkProvider clientProv = new BinaryClientFormatterSinkProvider();
            serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

            Hashtable properties = new System.Collections.Hashtable();
            properties.Add("port", 9000);

            TcpChannel tcp = new TcpChannel(properties, clientProv, serverProv);
            ChannelServices.RegisterChannel(tcp, false);

            EVSMiniServerInterface sm = (EVSMiniServerInterface)Activator.GetObject(typeof(EVSMiniServerInterface), "tcp://localhost:9900/MessageServer.rem");

            while (true)
            {
                if (sm == null)
                {
                    Console.WriteLine("Failed to communicate with remote server.");
                    return;
                }
                else
                {
                    Console.WriteLine("Enter message to send to server:");
                    string message = Console.ReadLine();
                    Console.WriteLine("Enter your name (sender):");
                    string sender = Console.ReadLine();
                    sm.ChangeGooditems(message, sender);
                }
            }
        }
    }
}

----------------------------------------------------------------------------------------
Avatar billede knaldeglad Nybegynder
31. juli 2006 - 20:57 #18
det er så smukt så smukt....    smid et svar og tusind tak...
Avatar billede md_craig Nybegynder
31. juli 2006 - 22:22 #19
Np...

Svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester