Results 1 to 3 of 3

Thread: Remoting, Events, Interfaces and Assemblies

  1. #1

    Thread Starter
    Hyperactive Member CyberHawke's Avatar
    Join Date
    May 2004
    Location
    Washington DC
    Posts
    477

    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:
    1. AddHandler m_IJobServer.JobEvent, AddressOf m_JobEventRepeater.Handler

    This is the entire code from the client:
    VB Code:
    1. Imports System
    2. Imports System.Runtime.Remoting
    3. Imports JobLib
    4.  
    5. Public Class Client : Inherits System.Windows.Forms.Form
    6.  
    7.     Private m_IJobServer As IJobServer
    8.     Private m_JobEventRepeater As JobEventRepeater
    9.  
    10.     Private Function GetIJobServer() As IJobServer
    11.         RemotingConfiguration.Configure("..\App.config")
    12.         Dim obj As Object = RemotingHelper.GetObject(GetType(IJobServer))
    13.         Return DirectCast(obj, IJobServer)
    14.     End Function
    15.  
    16.     Private Sub JobEventRepeater_JobEventHandler(ByVal sender As Object, ByVal args As JobEventArgs)
    17.         MessageBox.Show(args.Reason)
    18.     End Sub
    19.  
    20.     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    21.         Call m_IJobServer.CreateJob("My New Job")
    22.     End Sub
    23.  
    24.     Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    25.         Me.Close()
    26.     End Sub
    27.  
    28.     Private Sub Client_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    29.         m_IJobServer = GetIJobServer()
    30.         m_JobEventRepeater = New JobEventRepeater
    31.         AddHandler m_JobEventRepeater.JobEvent, AddressOf Me.JobEventRepeater_JobEventHandler
    32.         [COLOR=red]AddHandler m_IJobServer.JobEvent, AddressOf m_JobEventRepeater.Handler[/COLOR]
    33.     End Sub
    34. End Class
    35.  
    36. Class RemotingHelper
    37.     Private Shared _isInit As Boolean
    38.     Private Shared _wellKnownTypes As IDictionary
    39.  
    40.     Public Shared Function GetObject(ByVal _type As Type) As Object
    41.         If Not _isInit Then Call InitTypeCache()
    42.         Dim Entry As WellKnownClientTypeEntry = DirectCast(_wellKnownTypes(_type), WellKnownClientTypeEntry)
    43.         If (Entry Is Nothing) Then Throw New RemotingException("Type not found!")
    44.         Return Activator.GetObject(Entry.ObjectType, Entry.ObjectUrl)
    45.     End Function
    46.  
    47.     Public Shared Sub InitTypeCache()
    48.         _isInit = True
    49.         _wellKnownTypes = New Hashtable
    50.         For Each Entry As WellKnownClientTypeEntry In RemotingConfiguration.GetRegisteredWellKnownClientTypes
    51.             If Entry.ObjectType Is Nothing Then Throw New RemotingException("A configured type could not be found. Please check spelling")
    52.             _wellKnownTypes.Add(Entry.ObjectType, Entry)
    53.         Next
    54.     End Sub
    55. 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!

  2. #2

    Thread Starter
    Hyperactive Member CyberHawke's Avatar
    Join Date
    May 2004
    Location
    Washington DC
    Posts
    477
    *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!

  3. #3

    Thread Starter
    Hyperactive Member CyberHawke's Avatar
    Join Date
    May 2004
    Location
    Washington DC
    Posts
    477

    Lightbulb

    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
  •  



Click Here to Expand Forum to Full Width