[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Lee Gillie

6/29/2004 11:07:00 PM

Trying to create a "generic" notification facility. Basically I have a
number of services which currently use NT MAILSLOTS to broadcast their
in-progress status to desktops on the LAN. In the mailslot there is
usually complex delimited data as a string.

My .NET approach is to instead use a "message server service". Also
attempting to provide a component that will make either SOURCE or
CONSUMER objects. The SOURCE object has one simple "Send" method, and
accepts a parameter of type "Object". Am making a "Consumer" object
which posts an event, and again, a single parameter of type OBJECT. I
am attempting to hide all the infrastructure and remoting as much as
possible, from the caller of the component. The component is also
exposing a COM interface. The component makes either a source or
consumer conversation with the service via one single remoted
component, which can "broadcast" events to clients. All of this works
great when the notify parameter is a string. But falls flat when
trying to do this with an item of type OBJECT.

Here is my extreme lack of knowledge about serialization...

Via the remoting method, I was able to send from a SOURCE to the
server, and it makes it back to the CONSUMER in a separate process.
But the consumer is having trouble looking at the "object". I get
this:

Run-time exception thrown :
System.Runtime.Remoting.RemotingException - This remoting proxy has no
channel sink which means either the server has no registered server
channels that are listening, or this application has no suitable
client channel to talk to the server.

The "object" being sent through this system is a "class" using only
fundamental data types, such as string, integer, and so on. The class
is marked serializable, and I found a need to inherit from MarshaByRef
to get the send side to work.

My thought is that once I get this class instance serialized, it is
completely self contained. Yet the message seems to indciate the
CONSUMER is somehow trying to get back to some remoting host, or such.
Probably due to the MBR.

Any hints on preparing my generic "object" parameter to be fully
self-sufficient would be greatly appreciated. In my component I don't
have knowledge of my caller's classes. If I can, I would like to not
burden my caller to perform serialization and deserialization, if
possible.


Can what I am trying to do even be done?



2 Answers

Ken Kolda

6/30/2004 12:36:00 AM

0

The error you''re getting is, as you suspected, due to the fact that your
class derives from MarshalByRefObject. When the consumer gets the reference
to this object and attempts to invoke one of its methods, it must open a
remoting channel back to the source, since that''s where the object actually
resides. In this way, your "source" application acts as both client and
server. That''s not a problem, but it sounds like that''s not the model you''re
trying to create.

The issue is that you indicated that you don''t your message server service
to know about the client''s classes. If you mark your classes as Serializable
but not MBR, then the server must generally have the implementation
available for the class, since the clss will be deserialized on the server.
But, assuming your server service has no need to ever know what the
underlying object is (i.e. it just passes it to a consumer which DOES know
what type of object this is), you could do something like this:

Create two wrapper classes in a separate assembly than from your remoted
server service classes, call them SourceWrapper and ConsumerWrapper. The
SourceWrapper would look something like:

class SourceWrapper
{
public SourceWrapper(string serverUri)
{ // Save off Uri to instance variable }

public void Send(object o)
{
// Serialize object using BinaryFormatter to get byte array
// Call Activator.GetObject() to get the remoted Source object from
server
// Invoke Source object''s Send(), passing the bytes.
}
}

The ConsumerWrapper would, conversely look like:

class ConsumerWrapper : MarshalByRefObject
{
public event MessageArrivedEventHandler MessageArrived;

public ConsumerWrapper(string serverUri)
{
// Get the Consumer object from server and add an event handler or
callback for this instance
}

private onMessageArrived(byte[] data)
{
// Deserialize object using Binary formatter
// Raise MessageArrived event for client to be notified
}
}

In other words, the SourceWrapper handles the serialization and the
ConsumerWrapper handles the deserialization so the client app doesn''t have
to worry itself about how this works. The server service in between knows
nothing except how to pass byte arrays around, so it''s completely generic.

Hope that helps -
Ken


"Lee Gillie" <ANTISPAMIFICATION_lee@odp.com> wrote in message
news:esoOd3iXEHA.1356@TK2MSFTNGP09.phx.gbl...
> Trying to create a "generic" notification facility. Basically I have a
> number of services which currently use NT MAILSLOTS to broadcast their
> in-progress status to desktops on the LAN. In the mailslot there is
> usually complex delimited data as a string.
>
> My .NET approach is to instead use a "message server service". Also
> attempting to provide a component that will make either SOURCE or
> CONSUMER objects. The SOURCE object has one simple "Send" method, and
> accepts a parameter of type "Object". Am making a "Consumer" object
> which posts an event, and again, a single parameter of type OBJECT. I
> am attempting to hide all the infrastructure and remoting as much as
> possible, from the caller of the component. The component is also
> exposing a COM interface. The component makes either a source or
> consumer conversation with the service via one single remoted
> component, which can "broadcast" events to clients. All of this works
> great when the notify parameter is a string. But falls flat when
> trying to do this with an item of type OBJECT.
>
> Here is my extreme lack of knowledge about serialization...
>
> Via the remoting method, I was able to send from a SOURCE to the
> server, and it makes it back to the CONSUMER in a separate process.
> But the consumer is having trouble looking at the "object". I get
> this:
>
> Run-time exception thrown :
> System.Runtime.Remoting.RemotingException - This remoting proxy has no
> channel sink which means either the server has no registered server
> channels that are listening, or this application has no suitable
> client channel to talk to the server.
>
> The "object" being sent through this system is a "class" using only
> fundamental data types, such as string, integer, and so on. The class
> is marked serializable, and I found a need to inherit from MarshaByRef
> to get the send side to work.
>
> My thought is that once I get this class instance serialized, it is
> completely self contained. Yet the message seems to indciate the
> CONSUMER is somehow trying to get back to some remoting host, or such.
> Probably due to the MBR.
>
> Any hints on preparing my generic "object" parameter to be fully
> self-sufficient would be greatly appreciated. In my component I don''t
> have knowledge of my caller''s classes. If I can, I would like to not
> burden my caller to perform serialization and deserialization, if
> possible.
>
>
> Can what I am trying to do even be done?
>
>
>


Lee Gillie

6/30/2004 3:32:00 PM

0

VERY helpful Ken!!! I greatly appreciate your taking time to teach
this old dog some new tricks.

Best regards - Lee Gillie - Spokane, WA

"Ken Kolda" <ken.kolda@elliemae-nospamplease.com> wrote in message
news:uysBvpjXEHA.3044@TK2MSFTNGP09.phx.gbl...
> The error you''re getting is, as you suspected, due to the fact that
your
> class derives from MarshalByRefObject. When the consumer gets the
reference
> to this object and attempts to invoke one of its methods, it must
open a
> remoting channel back to the source, since that''s where the object
actually
> resides. In this way, your "source" application acts as both client
and
> server. That''s not a problem, but it sounds like that''s not the
model you''re
> trying to create.
>
> The issue is that you indicated that you don''t your message server
service
> to know about the client''s classes. If you mark your classes as
Serializable
> but not MBR, then the server must generally have the implementation
> available for the class, since the clss will be deserialized on the
server.
> But, assuming your server service has no need to ever know what the
> underlying object is (i.e. it just passes it to a consumer which
DOES know
> what type of object this is), you could do something like this:
>
> Create two wrapper classes in a separate assembly than from your
remoted
> server service classes, call them SourceWrapper and ConsumerWrapper.
The
> SourceWrapper would look something like:
>
> class SourceWrapper
> {
> public SourceWrapper(string serverUri)
> { // Save off Uri to instance variable }
>
> public void Send(object o)
> {
> // Serialize object using BinaryFormatter to get byte array
> // Call Activator.GetObject() to get the remoted Source
object from
> server
> // Invoke Source object''s Send(), passing the bytes.
> }
> }
>
> The ConsumerWrapper would, conversely look like:
>
> class ConsumerWrapper : MarshalByRefObject
> {
> public event MessageArrivedEventHandler MessageArrived;
>
> public ConsumerWrapper(string serverUri)
> {
> // Get the Consumer object from server and add an event
handler or
> callback for this instance
> }
>
> private onMessageArrived(byte[] data)
> {
> // Deserialize object using Binary formatter
> // Raise MessageArrived event for client to be notified
> }
> }
>
> In other words, the SourceWrapper handles the serialization and the
> ConsumerWrapper handles the deserialization so the client app
doesn''t have
> to worry itself about how this works. The server service in between
knows
> nothing except how to pass byte arrays around, so it''s completely
generic.
>
> Hope that helps -
> Ken
>
>
> "Lee Gillie" <ANTISPAMIFICATION_lee@odp.com> wrote in message
> news:esoOd3iXEHA.1356@TK2MSFTNGP09.phx.gbl...
> > Trying to create a "generic" notification facility. Basically I
have a
> > number of services which currently use NT MAILSLOTS to broadcast
their
> > in-progress status to desktops on the LAN. In the mailslot there
is
> > usually complex delimited data as a string.
> >
> > My .NET approach is to instead use a "message server service".
Also
> > attempting to provide a component that will make either SOURCE or
> > CONSUMER objects. The SOURCE object has one simple "Send" method,
and
> > accepts a parameter of type "Object". Am making a "Consumer"
object
> > which posts an event, and again, a single parameter of type
OBJECT. I
> > am attempting to hide all the infrastructure and remoting as much
as
> > possible, from the caller of the component. The component is also
> > exposing a COM interface. The component makes either a source or
> > consumer conversation with the service via one single remoted
> > component, which can "broadcast" events to clients. All of this
works
> > great when the notify parameter is a string. But falls flat when
> > trying to do this with an item of type OBJECT.
> >
> > Here is my extreme lack of knowledge about serialization...
> >
> > Via the remoting method, I was able to send from a SOURCE to the
> > server, and it makes it back to the CONSUMER in a separate
process.
> > But the consumer is having trouble looking at the "object". I get
> > this:
> >
> > Run-time exception thrown :
> > System.Runtime.Remoting.RemotingException - This remoting proxy
has no
> > channel sink which means either the server has no registered
server
> > channels that are listening, or this application has no suitable
> > client channel to talk to the server.
> >
> > The "object" being sent through this system is a "class" using
only
> > fundamental data types, such as string, integer, and so on. The
class
> > is marked serializable, and I found a need to inherit from
MarshaByRef
> > to get the send side to work.
> >
> > My thought is that once I get this class instance serialized, it
is
> > completely self contained. Yet the message seems to indciate the
> > CONSUMER is somehow trying to get back to some remoting host, or
such.
> > Probably due to the MBR.
> >
> > Any hints on preparing my generic "object" parameter to be fully
> > self-sufficient would be greatly appreciated. In my component I
don''t
> > have knowledge of my caller''s classes. If I can, I would like to
not
> > burden my caller to perform serialization and deserialization, if
> > possible.
> >
> >
> > Can what I am trying to do even be done?
> >
> >
> >
>
>