|
-
Nov 2nd, 2004, 01:23 PM
#1
Thread Starter
Hyperactive Member
Remoting, Events, Interfaces and Assemblies
Greetings,
I have a test program that I am playing with which uses interfaces to instantiate remote objects. The interface is defined in one assembly, with an EventRepeater class which should handle the registration and firing of an event raised from the server. A server object which implements my interface is defined in a different assembly while the actual server application is defined in a third. And finally, my client is defined in a separate assembly that will reside of course on the client machine. The Server class assembly has a reference to the Interface library as does the server application and the client. The client does not contain a reference to the server assembly, nor should it need to as this is "Remoting" afterall. When I start my server, everything runs fine. When I start my client everything is fine until I get to this line:
VB Code:
AddHandler m_IJobServer.JobEvent, AddressOf m_JobEventRepeater.Handler
This is the entire code from the client:
VB Code:
Imports System
Imports System.Runtime.Remoting
Imports JobLib
Public Class Client : Inherits System.Windows.Forms.Form
Private m_IJobServer As IJobServer
Private m_JobEventRepeater As JobEventRepeater
Private Function GetIJobServer() As IJobServer
RemotingConfiguration.Configure("..\App.config")
Dim obj As Object = RemotingHelper.GetObject(GetType(IJobServer))
Return DirectCast(obj, IJobServer)
End Function
Private Sub JobEventRepeater_JobEventHandler(ByVal sender As Object, ByVal args As JobEventArgs)
MessageBox.Show(args.Reason)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Call m_IJobServer.CreateJob("My New Job")
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Me.Close()
End Sub
Private Sub Client_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
m_IJobServer = GetIJobServer()
m_JobEventRepeater = New JobEventRepeater
AddHandler m_JobEventRepeater.JobEvent, AddressOf Me.JobEventRepeater_JobEventHandler
[COLOR=red]AddHandler m_IJobServer.JobEvent, AddressOf m_JobEventRepeater.Handler[/COLOR]
End Sub
End Class
Class RemotingHelper
Private Shared _isInit As Boolean
Private Shared _wellKnownTypes As IDictionary
Public Shared Function GetObject(ByVal _type As Type) As Object
If Not _isInit Then Call InitTypeCache()
Dim Entry As WellKnownClientTypeEntry = DirectCast(_wellKnownTypes(_type), WellKnownClientTypeEntry)
If (Entry Is Nothing) Then Throw New RemotingException("Type not found!")
Return Activator.GetObject(Entry.ObjectType, Entry.ObjectUrl)
End Function
Public Shared Sub InitTypeCache()
_isInit = True
_wellKnownTypes = New Hashtable
For Each Entry As WellKnownClientTypeEntry In RemotingConfiguration.GetRegisteredWellKnownClientTypes
If Entry.ObjectType Is Nothing Then Throw New RemotingException("A configured type could not be found. Please check spelling")
_wellKnownTypes.Add(Entry.ObjectType, Entry)
Next
End Sub
End Class
This is the config file for the client:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application name="JobClient">
<client>
<wellknown type="JobLib.IJobServer, JobLib" url="tcp://localhost:81/JobServer" />
</client>
<channels>
<channel ref="tcp" port="0">
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
<clientProviders>
<formatter ref="binary" />
</clientProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
The error I am receiving is:
Additional information: Type System.DelegateSerializationHolder and the types derived from it (such as System.DelegateSerializationHolder) are not permitted to be deserialized at this security level.
and I have come to understand that you receive this error when you have not set the typeFilterLevel to "Full". I have done this as can be seen in the configuration file above.
I have sent Ingo Rammer a couple of emails but I guess with his busy schedule he has not had time to respond. Do any of you have any thoughts on what might be causing my application to throw this exception?
Any help or suggestions would be greatly appreciated (provided they work )
Whadayamean it doesn't work....
It works fine on my machine!

-
Nov 3rd, 2004, 06:39 AM
#2
Thread Starter
Hyperactive Member
*bump*
Any one here got a clue
I can post additional source code if needed. If you would like to see code from any of the other assemblies, I'll be happy to post.
John
Whadayamean it doesn't work....
It works fine on my machine!

-
Nov 10th, 2004, 01:42 PM
#3
Thread Starter
Hyperactive Member
Ok, first of all, it shoud be known that I have written a remoting project in C# prior to attempting to write this one in VB. Armed with the previous experience, I figured that doing this in VB would be a no brainer and actually, it was. The hooking up of events in a VB remoting project was very different from C#, but the general principal is the same. I had scoured the net, bought a few books, and still I couldn't get this thing to work. So I said what the heck, I'll load it on a different machine (just in case it was actually a security permissions issue) to see if it works from a diferent box.
Well, I received the same error message on a box I know I have full permissions on so I figured that it absolutely cannot be that, but what then? Well I start looking through my remoting configuration and low and behold I had the capitalization on a single letter incorrect, and the &^%$(*^% thing was broken.
Sheesh!!!
Well, how does it all work you might ask?
Well, I built an assembly that contains my interface definitions and a class for repeating events. I compiled that and added a reference to a new assembly that contains my actual server class code, and declared a class that implements the interface. I coded the class to update a database and pass back a message that indicates a success or failure. I then created a client, added a reference to my interface assembly and then declared instances of objects that were of type ISomeInterface and used remoting to connect the dots.
I have seen a lot of remoting references out there on the net, but none of them were doing it exactly the way I wanted. Most offered up solutions where the Interfaces and the server object were contained in the same assembly which is definitely not cool if you want to recode your server, because then you are redistributing your server assembly to all your clients, which really sort of negates the usefulness of interfaces and remote objects.
The important thing that I managed to do in my solution was to seaparate my interfaces from the implentation assemblies, and purely through remoting instantiate a remote object (to which I had absolutely NO reference to in my client code) using just an interface definition.
What does this mean? If I never change my interface (which I shouldn't) then if I find it necessary to recode my server to make some arbitrary change, the clients will never know about it. It is a complete separation of server and client code.
Maybe not the most interesting thing you have read on the net lately, but for me, it's a big hurdle due to the way some processes need to run within my organization.
I will type up a tutorial along with explanations of what does and does not work along with a complete working example in the not so distant future. I hope that my efforts may benefit you all at some point.
Thanks for taking the time to read
Whadayamean it doesn't work....
It works fine on my machine!

Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|