Laden...

Remote .Net Events Exception

Erstellt von John444 vor 17 Jahren Letzter Beitrag vor 17 Jahren 3.449 Views
J
John444 Themenstarter:in
42 Beiträge seit 2005
vor 17 Jahren
Remote .Net Events Exception

Hallo User...

hab eine Client Server Anwendung mit .Net Remoting gebaut.
Habe auch ein Singleton Objekt was ich durch die gegend schicken kann... funktioniert alles wunderbar...

Jetzt will ich die ganze Sache noch um Events erweitern.
Da hänge ich...

Hier mein Prog.

Die Business Klasse: RemService.dll



using System;

namespace RemService
{
	public delegate void GetData();
	public class ClsService: MarshalByRefObject
	{
		private int myValue;
		public event GetData evtGetData;

		public int addValue(int add)
		{
			return this.myValue+=add;
		}
		public int getValue()
		{
			return this.myValue;
		}
		public void setValue(int x)
		{
			this.myValue = x;
			evtGetData();
		}
	}
}



Der Server hält die B-Klasse am leben RemServer.exe


...
RemotingConfiguration.Configure("RemServer.exe.config");
mySingletonRem = new ClsService();
this.txtInfo.Text = "Server is running...";
...

mySingletonRem.setValue(5); //In dieser Fkt wird der Event ausgelöst

Die RemServer.exe.config sieht so aus:


<?xml version="1.0" encoding="utf-8" ?> 
<configuration>
	<system.runtime.remoting>
		<application name="RemService">
			<channels>
				<channel ref="http" port="8990"/>
			</channels>
			<service>
				<wellknown
					mode="Singleton"
					type="RemService.ClsService, RemService"
					objectUri="MySingleton.soap"
				/>
			</service>
		</application>
	</system.runtime.remoting>
</configuration>

Der Client: RemClient.exe


public void cmdConnect_Click(object sender, System.EventArgs e)
		{
			
			RemotingConfiguration.Configure("RemClient.exe.config");
			
			mySingletonRem = new ClsService();
			
			txtInfo.Text = "Client connect...";
			int a = mySingletonRem.addValue(1); //Funktioniert super auch bei vielen Clients.
			
			try
			{
				mySingletonRem.evtGetData += new GetData(this.ReceiveData); // Hier kommt die Exception siehe unten
			}
			catch (Exception exp)
			{
				MessageBox.Show (exp.ToString() + exp.Message);
				this.Close();
			}

			this.cmdConnect.Enabled = false;
		}
		
		public void ReceiveData()
		{
			txtData.Text = mySingletonRem.getValue().ToString();
		}

Die RemClient.exe.config sieht so aus



<?xml version="1.0" encoding="utf-8" ?> 
<configuration>
  <system.runtime.remoting>
    <application name="RemService">
      <channels>
        <channel ref="http" port="8991"/>
      </channels>
      <client>
        <wellknown 
            type="RemService.ClsService, RemService" 
            url="http://localhost:8990/RemService/MySingleton.soap" 
         />
      </client>
    </application>
  </system.runtime.remoting>
</configuration>


Folgende Exception kommt beim andocken an das Event.


System.Security.SecurityException: Type System.DelegateSerializationHolder and the types derived from it (such as System.DelegateSerializationHolder) are not permitted to be deserialized at this security level.

Server stack trace: 
   at System.Runtime.Serialization.FormatterServices.CheckTypeSecurity(Type t, TypeFilterLevel securityLevel)
   at System.Runtime.Serialization.Formatters.Soap.ObjectReader.CheckSecurity(ParseRecord pr)
   at System.Runtime.Serialization.Formatters.Soap.ObjectReader.ParseObject(ParseRecord pr)
   at System.Runtime.Serialization.Formatters.Soap.ObjectReader.Parse(ParseRecord pr)
   at System.Runtime.Serialization.Formatters.Soap.SoapHandler.StartChildren()
   at System.Runtime.Serialization.Formatters.Soap.SoapParser.ParseXml()
   at System.Runtime.Serialization.Formatters.Soap.SoapParser.Run()
   at System.Runtime.Serialization.Formatters.Soap.ObjectReader.Deserialize(HeaderHandler handler, ISerParser serParser)
   at System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Deserialize(Stream serializationStream, HeaderHandler handler)
   at System.Runtime.Remoting.Channels.CoreChannel.DeserializeSoapRequestMessage(Stream inputStream, Header[] h, Boolean bStrictBinding, TypeFilterLevel securityLevel)
   at System.Runtime.Remoting.Channels.SoapServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, IMessage& responseMsg, ITransportHeaders& responseHeaders, Stream& responseStream)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at RemService.ClsService.add_evtGetData(GetData value)
   at RemClient.frmClient.cmdConnect_Click(Object sender, EventArgs e) in d:\data\src\test\remclient\frmclient.cs:line 134Type System.DelegateSerializationHolder and the types derived from it (such as System.DelegateSerializationHolder) are not permitted to be deserialized at this security level.


Bin über jede Hilfe dankbar.

Der oben stehende Code kann auch gut als einfaches Remoting Bsp genutzt werden. Das funktioniert ja...

L
667 Beiträge seit 2004
vor 17 Jahren

Hi, das liegt daran, dass Du beim Definieren des Remoting-Channels deinen TypeFilterLevel auf "Full" setzen musst, damit Du events verschicken kannst.

Wie das über die Config-Datei geht weiss ich jetzt nicht, aber hier ein Codeausschnitt aus einem meiner Projekte :


BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
			BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
			serverProvider.TypeFilterLevel = TypeFilterLevel.Full;

			IDictionary props = new Hashtable();

			props["port"] = 0;
			string s = System.Guid.NewGuid().ToString();
			props["name"] = s;
			props["typeFilterLevel"] = TypeFilterLevel.Full;
			channel = new TcpChannel(props,clientProvider,serverProvider);
			ChannelServices.RegisterChannel(channel);

"It is not wise to be wise" - Sun Tzu

J
John444 Themenstarter:in
42 Beiträge seit 2005
vor 17 Jahren

Hi Lynix,

danke für die schnelle Hilfe.
So ganz verstehe ich es aber noch nicht.

Soll das was du da gespostet hast in den Client? Wie komme ich dann an mein B-Klasse Objekt?

Kann es irgendwie auch nicht testen, weil bir mir

System.Runtime.Remoting.Channels.BinaryClientFormatterSinkProvider

schon nicht existiert... ist das nur in .Net 2.0 drin?
hmm in der msdn steht auch 1.1 🤔

wenn du ein etwas ausführlicheres Bsp. mit Client / Server hättest wäre ich dir dankbar.

J
John444 Themenstarter:in
42 Beiträge seit 2005
vor 17 Jahren

ich hab zwar gefunden wie man das in die config Datei schreibt...

funktioniert aber auch nicht, gleiche Exception

hier die neue Config Datei. Vielleicht hab ich ja was falsch gemacht.



<?xml version="1.0" encoding="utf-8" ?> 
<configuration>
  <system.runtime.remoting>
    <application name="RemService">
      <channels>
        <channel ref="http" port="8991"/>
        <serverProviders>
			<formatter ref="binary" typeFilterLevel="Full" />
		</serverProviders>
      </channels>
      <client>
        <wellknown 
            type="RemService.ClsService, RemService" 
            url="http://localhost:8990/RemService/MySingleton.soap" 
         />
      </client>
    </application>
  </system.runtime.remoting>
</configuration>


J
John444 Themenstarter:in
42 Beiträge seit 2005
vor 17 Jahren

Original von John444
Kann es irgendwie auch nicht testen, weil bir mir

System.Runtime.Remoting.Channels.BinaryClientFormatterSinkProvider  

schon nicht existiert... ist das nur in .Net 2.0 drin?
hmm in der msdn steht auch 1.1 🤔

Ok, das hab ich mir schon selber beantwortet.
man muss dafür die System.Runtime.Remoting.dll einfügen

L
667 Beiträge seit 2004
vor 17 Jahren

Hallo John, ja das Ganze gehört in den Client. Hier mal mein kompletter Client-Code, der sich auf die Verbindung bezieht :

Das Ganze ist wohlgemerkt aus einem etwas älteren Projekt, und mittlerweile hab ich mir so eklige Sachen wie Remoting abgewöhnt. Von daher kenne ich auch nimmer alle Zusammenhänge so ganz genau.


//Protokoll-Schema der Anwendung festlegen
string URI = "MyApp";
string protocolScheme = "tcp://" + computerName + ":" + portNo.ToString() + "/" + URI;

//Providers initialisieren
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();

//Provider-Rechte des Servers auf TypeFilterLevel.Full setzen
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;

//Channel für die Verbindung konfigurieren
IDictionary props = new Hashtable();

//Port 0 bedeutet "such dir einen freien Port aus"
props["port"] = 0;

//einen eindeutigen Namen für diesen Channel vergeben
string s = System.Guid.NewGuid().ToString();
props["name"] = s;

//TypeFilterLevel der Client-Verbindung auf "Full" setzen
props["typeFilterLevel"] = TypeFilterLevel.Full;

//TCPChannel initialisieren
channel = new TcpChannel(props,clientProvider,serverProvider);

//channel registrieren
ChannelServices.RegisterChannel(channel);

//Verbindung herstellen
MyRemoteObject mServer = (MyRemoteObject)Activator.GetObject(typeof(MyRemoteObject), protocolScheme);

Ich benutze auch .NET Framework Version 1.1 - die SinkProviders sind also definitiv da zu finden. In welchem Namespace die stecken musst Du in der MSDN selber nachschauen, da ich hier grad keine IDE hab und auch kein Nerv selbst durch die MSDN zu suchen.

Folgende Namespaces hab ich aber bei mir eingebunden (einer davon wirds dann wohl sein g)


using System;
using System.Drawing;
using System.Reflection;
using System.Collections;
using System.Collections.Specialized;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.Net;
using System.Net.Sockets;

Probier mal weiter, es liegt auf jeden Fall am Typefilterlevel. Ich hatte damals genau dasselbe Problem und kann mich daher noch gut an den Grund erinnern.

"It is not wise to be wise" - Sun Tzu

M
40 Beiträge seit 2006
vor 17 Jahren

hier gibts auch noch ein etwas genaueres beispiel