Thread View: borland.public.cppbuilder.internet.socket
24 messages
24 total messages
Started by Gary D
Sat, 22 Oct 2005 01:18
sockets????
Author: Gary D
Date: Sat, 22 Oct 2005 01:18
Date: Sat, 22 Oct 2005 01:18
18 lines
1689 bytes
1689 bytes
I need to have a one way broadcast from a "server" to multiple clients, here is the scenario: A server watches for events that happen in special situations, this part of my program is already runnig, BUT I need to add code that can broadcast (unsolicited) that the event(s) occurred. At that point any client that happened to be listening could update itself without having to watch all the same things the server is already watching. Is a socket the best way to do this? I have looked into COM and found that COM servers will not broadcast an unsolicited message. I can probably work around this but wish I didn't have to because the server will have to do extra work holding open a triggered event until something happens to complete the sequence.
Re: sockets????
Author: Remy Lebeau (TeamB)
Date: Sat, 22 Oct 2005 02:11
Date: Sat, 22 Oct 2005 02:11
25 lines
1797 bytes
1797 bytes
"Gary D" <gcdesroches@nctc.com> wrote in message news:43599303@newsgroups.borland.com... > Is a socket the best way to do this? A socket is one way to do it. > I have looked into COM and found that COM servers > will not broadcast an unsolicited message. Yes, they will. I have COM servers that broadcast events just fine. > the server will have to do extra work holding open a triggered > event until something happens to complete the sequence. Use multiple threads. Have one thread monitoring the events, then have another thread that broadcasts events to clients. When a monitored event occurs, copy the relative information to a queue in the broadcast thread and then go back to monitoring for new events. This way, the broadast thread is run in parallel to the monitoring thread and the monitoring is not waiting for the broadcast to finish, and vice versa. Gambit
Re: sockets????
Author: Gary D
Date: Sun, 23 Oct 2005 16:37
Date: Sun, 23 Oct 2005 16:37
46 lines
2740 bytes
2740 bytes
If you can make a COM server broadcast without needing a request from a client can you tell me how you did it? Borland support says it can't be done. ( Remember it's an UNSOLICITED broadcast I'm after, no client involvment other than receiving ) I have multi-threads running already so that part you could skip. I have a server client demo running also, so the only thing I need to see is how you get around the server's need for the request from the client. BTW, I don't even need to send any "data" I just need the server to fire an event in the client. That event will already contain everything the client needs. "Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message news:43599f5f$1@newsgroups.borland.com... > > "Gary D" <gcdesroches@nctc.com> wrote in message > news:43599303@newsgroups.borland.com... > >> Is a socket the best way to do this? > > A socket is one way to do it. > >> I have looked into COM and found that COM servers >> will not broadcast an unsolicited message. > > Yes, they will. I have COM servers that broadcast events just fine. > >> the server will have to do extra work holding open a triggered >> event until something happens to complete the sequence. > > Use multiple threads. Have one thread monitoring the events, then have > another thread that broadcasts events to clients. When a monitored event > occurs, copy the relative information to a queue in the broadcast thread > and > then go back to monitoring for new events. This way, the broadast thread > is > run in parallel to the monitoring thread and the monitoring is not waiting > for the broadcast to finish, and vice versa. > > > Gambit > >
Re: sockets????
Author: Remy Lebeau (TeamB)
Date: Sun, 23 Oct 2005 17:10
Date: Sun, 23 Oct 2005 17:10
48 lines
3176 bytes
3176 bytes
"Gary D" <gcdesroches@nctc.com> wrote in message
news:435bbbf2$1@newsgroups.borland.com...
> If you can make a COM server broadcast without needing a request
> from a client can you tell me how you did it?
Event sinks. A client registers a sink with the server, and then the server
can trigger events to that sink whenever it wants. A common way to do that
is via Connection Points. When you create a new COM object in the IDE's
ActiveX wizards, you have an option to "Generate Event Support". This
option adds an additional IDispatch-derived interface to your Type Library
where you can then define your event methods. The COM object's Impl class
will then have a TEvent_... class added to its ancestor list which
implements Fire_...() methods for the events. The server code can call
these methods at any time to trigger events in connected clients. The
client's code can then derive a class from that interface, or alternatively
use the VCL's TEventDispatcher class, to implement the event handling as
needed. In the case of TEventDispatcher, it has a ConnnectServer() method
that you can use to hook up the TEventDispatcher to your COM object
instance. If you don't use TEventDispatcher, then you have to manually
query the COM object for the IConnectionPointContainer interface, call its
FindConnectionPoint() method to get an IConnectionPoint interface, and then
finally call its Advise() method passing it an instance of your sink class.
Refer to the following articles for more details:
Events/Callbacks
http://www.techvanguards.com/com/concepts/events.asp
Implementing an Event Framework
http://www.techvanguards.com/com/tutorials/eventsystem.asp
The code examples are in Delphi, but the concepts can be applied to C++ as
well.
> Borland support says it can't be done.
What EXACTLY was said?
> ( Remember it's an UNSOLICITED broadcast I'm after, no client
> involvment other than receiving )
The client has to register its interest in receiving events. You can do
that right after instantiating the COM object.
Gambit
Re: sockets????
Author: Gary D
Date: Mon, 24 Oct 2005 10:38
Date: Mon, 24 Oct 2005 10:38
60 lines
3616 bytes
3616 bytes
Thank you for the help, I am totally new at COM so I have had a rough ride even getting this far. I at least understand what I'm reading here now. I will try to work through your explanation and see if I can get it to work. Gary D "Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message news:435bc353$1@newsgroups.borland.com... > > "Gary D" <gcdesroches@nctc.com> wrote in message > news:435bbbf2$1@newsgroups.borland.com... > >> If you can make a COM server broadcast without needing a request >> from a client can you tell me how you did it? > > Event sinks. A client registers a sink with the server, and then the > server can trigger events to that sink whenever it wants. A common way to > do that is via Connection Points. When you create a new COM object in the > IDE's ActiveX wizards, you have an option to "Generate Event Support". > This option adds an additional IDispatch-derived interface to your Type > Library where you can then define your event methods. The COM object's > Impl class will then have a TEvent_... class added to its ancestor list > which implements Fire_...() methods for the events. The server code can > call these methods at any time to trigger events in connected clients. > The client's code can then derive a class from that interface, or > alternatively use the VCL's TEventDispatcher class, to implement the event > handling as needed. In the case of TEventDispatcher, it has a > ConnnectServer() method that you can use to hook up the TEventDispatcher > to your COM object instance. If you don't use TEventDispatcher, then you > have to manually query the COM object for the IConnectionPointContainer > interface, call its FindConnectionPoint() method to get an > IConnectionPoint interface, and then finally call its Advise() method > passing it an instance of your sink class. > > Refer to the following articles for more details: > > Events/Callbacks > http://www.techvanguards.com/com/concepts/events.asp > > Implementing an Event Framework > http://www.techvanguards.com/com/tutorials/eventsystem.asp > > The code examples are in Delphi, but the concepts can be applied to C++ as > well. > >> Borland support says it can't be done. > > What EXACTLY was said? > >> ( Remember it's an UNSOLICITED broadcast I'm after, no client >> involvment other than receiving ) > > The client has to register its interest in receiving events. You can do > that right after instantiating the COM object. > > > Gambit >
Re: sockets????
Author: Gary D
Date: Tue, 25 Oct 2005 21:54
Date: Tue, 25 Oct 2005 21:54
89 lines
4567 bytes
4567 bytes
Sorry I didn't answer your question about what exactly was said. Here is the
complete text:
My Question was:
Why can't the server just call Trigger() itself? // NOTE: Trigger is the
function that the server owns that responds to client requests.
somefunction()
{
Doing the server thing...
if( Oh, look! Something important happened!...)
Trigger();
}
That would accomplish what I am after because the message box would become:
void __fastcall TForm1::OnEvent1(BSTR* Message)
{
// ShowMessage("Fired now");
Do the refresh_info_thing();
}
???? Gary
and the answer came back:
Servers don't really have that kind of logic. They pretty much sit
there and wait for requests from clients. In other words, servers aren't
supposed to "push out" services on their own; they're only supposed to wait
for clients to request services and then fulfill those requests.
Another way to see it is that servers aren't designed to sit there
executing code on their own. They only spring to action when a client tells
them to. A COM server isn't any different.
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:435bc353$1@newsgroups.borland.com...
>
> "Gary D" <gcdesroches@nctc.com> wrote in message
> news:435bbbf2$1@newsgroups.borland.com...
>
>> If you can make a COM server broadcast without needing a request
>> from a client can you tell me how you did it?
>
> Event sinks. A client registers a sink with the server, and then the
> server can trigger events to that sink whenever it wants. A common way to
> do that is via Connection Points. When you create a new COM object in the
> IDE's ActiveX wizards, you have an option to "Generate Event Support".
> This option adds an additional IDispatch-derived interface to your Type
> Library where you can then define your event methods. The COM object's
> Impl class will then have a TEvent_... class added to its ancestor list
> which implements Fire_...() methods for the events. The server code can
> call these methods at any time to trigger events in connected clients.
> The client's code can then derive a class from that interface, or
> alternatively use the VCL's TEventDispatcher class, to implement the event
> handling as needed. In the case of TEventDispatcher, it has a
> ConnnectServer() method that you can use to hook up the TEventDispatcher
> to your COM object instance. If you don't use TEventDispatcher, then you
> have to manually query the COM object for the IConnectionPointContainer
> interface, call its FindConnectionPoint() method to get an
> IConnectionPoint interface, and then finally call its Advise() method
> passing it an instance of your sink class.
>
> Refer to the following articles for more details:
>
> Events/Callbacks
> http://www.techvanguards.com/com/concepts/events.asp
>
> Implementing an Event Framework
> http://www.techvanguards.com/com/tutorials/eventsystem.asp
>
> The code examples are in Delphi, but the concepts can be applied to C++ as
> well.
>
>> Borland support says it can't be done.
>
> What EXACTLY was said?
>
>> ( Remember it's an UNSOLICITED broadcast I'm after, no client
>> involvment other than receiving )
>
> The client has to register its interest in receiving events. You can do
> that right after instantiating the COM object.
>
>
> Gambit
>
Re: sockets????
Author: Remy Lebeau (TeamB)
Date: Tue, 25 Oct 2005 22:37
Date: Tue, 25 Oct 2005 22:37
24 lines
2056 bytes
2056 bytes
"Gary D" <gcdesroches@nctc.com> wrote in message news:435ea916$1@newsgroups.borland.com... > Why can't the server just call Trigger() itself? // NOTE: Trigger > is the function that the server owns that responds to client requests. The server *CAN* call Trigger() whenever it needs to. Trigger() can then call the Fire_...() method for whichever event(s) its wants to, and those events will be called in the client's event sink. > and the answer came back: Borland's answer is completely wrong. Servers *DO* have that kind of logic available. Connection Points are designed exactly to handle the kind of Push model that Borland says servers can't have. I know it works because I have several COM servers that push unsolicited events to clients in response to external triggers (hardware events, file changes, etc). Also, it is possible to design a COM server inside an NT service, such that the COM server *IS* executing code on its own without having any clients connected at all. Gambit
Re: sockets????
Author: Gary D
Date: Sat, 29 Oct 2005 12:15
Date: Sat, 29 Oct 2005 12:15
67 lines
3835 bytes
3835 bytes
This is the code that creates a server connection and fires the event ( in
the demo I was given nothing is done but to display a messagebox )
void __fastcall TClientWin::Button1Click(TObject *Sender)
{
FTestEventsImpl = CoTestEventsImpl::Create();
FEventSink.OnEvent1 = OnEvent1;
FEventSink.Connect(FTestEventsImpl);
FTestEventsImpl.Trigger();
}
//---------------------------------------------------------------------------
void __fastcall TClientWin::OnEvent1(BSTR* Message)
{
ShowMessage("Client Event Fired");
}
//---------------------------------------------------------------------------
The server is a blank window. It just appears(when the FTestEventsImpl =
CoTestEventsImpl::Create(); code executes? )
everything else is done in the COM library / Library table. ( right??)
I do not understand COM at all outside of intellectually knowing what it
does.
Borland is no help, I paid them like $2000.00 for tech support to have them
tell me I can't do what you say I can do.
PLEASE, can you tell me what to do to get the server to fire the OnEvent1 of
the client when the SERVER wants to
and not because the client asked? I understand that the client must connect
first to announce it self, but I don't understand
how to access the connection at the server's end once it is inplace. I have
tried for days and only became more frustrated.
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:435eb30b@newsgroups.borland.com...
>
> "Gary D" <gcdesroches@nctc.com> wrote in message
> news:435ea916$1@newsgroups.borland.com...
>
>> Why can't the server just call Trigger() itself? // NOTE: Trigger
>> is the function that the server owns that responds to client requests.
>
> The server *CAN* call Trigger() whenever it needs to. Trigger() can then
> call the Fire_...() method for whichever event(s) its wants to, and those
> events will be called in the client's event sink.
>
>> and the answer came back:
>
> Borland's answer is completely wrong. Servers *DO* have that kind of
> logic
> available. Connection Points are designed exactly to handle the kind of
> Push model that Borland says servers can't have. I know it works because
> I
> have several COM servers that push unsolicited events to clients in
> response
> to external triggers (hardware events, file changes, etc). Also, it is
> possible to design a COM server inside an NT service, such that the COM
> server *IS* executing code on its own without having any clients connected
> at all.
>
>
> Gambit
>
>
Re: sockets????
Author: Gary D
Date: Sat, 29 Oct 2005 12:30
Date: Sat, 29 Oct 2005 12:30
58 lines
3193 bytes
3193 bytes
Let me ask a more specific question...
This is the Trigger() code in the server:
STDMETHODIMP TTestEventsImplImpl::Trigger()
{
WideString strName;
bool Fire_The_Event = true;
if ( Fire_The_Event == true )
Fire_Event1(&strName);
return S_OK;
}
The bool Fire_The_Event = 1; if( Fire_The_Event == ??? ) is supposed to show
that if Fire_The_Event is true the event fires and if not it won't.
I get that.
So here is the thing I am stuck on. How do I replace a local bool with an
external one which will use the client's existing connection?
( and accept new connections ) I can't figure out how to access Trigger()
inside the Server Code at all, let alone get an instance of it
that has active connection(s) to the client(s).
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:435eb30b@newsgroups.borland.com...
>
> "Gary D" <gcdesroches@nctc.com> wrote in message
> news:435ea916$1@newsgroups.borland.com...
>
>> Why can't the server just call Trigger() itself? // NOTE: Trigger
>> is the function that the server owns that responds to client requests.
>
> The server *CAN* call Trigger() whenever it needs to. Trigger() can then
> call the Fire_...() method for whichever event(s) its wants to, and those
> events will be called in the client's event sink.
>
>> and the answer came back:
>
> Borland's answer is completely wrong. Servers *DO* have that kind of
> logic
> available. Connection Points are designed exactly to handle the kind of
> Push model that Borland says servers can't have. I know it works because
> I
> have several COM servers that push unsolicited events to clients in
> response
> to external triggers (hardware events, file changes, etc). Also, it is
> possible to design a COM server inside an NT service, such that the COM
> server *IS* executing code on its own without having any clients connected
> at all.
>
>
> Gambit
>
>
Re: sockets????
Author: Remy Lebeau (TeamB)
Date: Sat, 29 Oct 2005 18:24
Date: Sat, 29 Oct 2005 18:24
17 lines
1795 bytes
1795 bytes
"Gary D" <gcdesroches@nctc.com> wrote in message news:436367ef$1@newsgroups.borland.com... > This is the code that creates a server connection and fires the event And? Does it actually work for you? > PLEASE, can you tell me what to do to get the server to > fire the OnEvent1 of the client when the SERVER wants > to and not because the client asked? I already told you earlier what to do on the server side - call the Fire_...() method for the event wheverever you want to. Gambit
Re: sockets????
Author: Remy Lebeau (TeamB)
Date: Sat, 29 Oct 2005 18:28
Date: Sat, 29 Oct 2005 18:28
36 lines
2254 bytes
2254 bytes
"Gary D" <gcdesroches@nctc.com> wrote in message
news:43636b7d@newsgroups.borland.com...
> Fire_Event1(&strName);
You should not be using the & operator there:
Fire_Event1(strName);
> So here is the thing I am stuck on. How do I replace a local bool
> with an external one which will use the client's existing connection?
You don't.
> ( and accept new connections )
That is handled automatically by COM for you. Every time
TTestEventsImplImpl is instantiated, that instance represents a new client
connection.
> I can't figure out how to access Trigger() inside the Server Code at all
Trigger() should be a public method of the TTestEventsImplImpl class. Given
a pointer to a TTestEventsImplImpl instance, you can call Trigger() on it.
> let alone get an instance of it that has active connection(s) to the
client(s).
Simply keep a list of instantiated TTestEventsImplImpl instances. In
TTestEventsImplImpl's constructor, add the 'this' pointer to the list. In
the destructor, remove the 'this' pointer from the list. Then the server
can loop through the list when needed.
Gambit
Re: sockets????
Author: Gary D
Date: Sat, 29 Oct 2005 21:42
Date: Sat, 29 Oct 2005 21:42
25 lines
2048 bytes
2048 bytes
Yes the demo works perfectly but I didn't write it, Borland support did. I do not understand how it works only that it does. "Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message news:4363be5e$1@newsgroups.borland.com... > > "Gary D" <gcdesroches@nctc.com> wrote in message > news:436367ef$1@newsgroups.borland.com... > >> This is the code that creates a server connection and fires the event > > And? Does it actually work for you? > >> PLEASE, can you tell me what to do to get the server to >> fire the OnEvent1 of the client when the SERVER wants >> to and not because the client asked? > > I already told you earlier what to do on the server side - call the > Fire_...() method for the event wheverever you want to. > > > Gambit > >
Re: sockets????
Author: Gary D
Date: Sat, 29 Oct 2005 22:01
Date: Sat, 29 Oct 2005 22:01
104 lines
4473 bytes
4473 bytes
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:4363bf65$1@newsgroups.borland.com...
>
>> Fire_Event1(&strName);
>
> You should not be using the & operator there:
>
> Fire_Event1(strName);
OK, its not important as it isn't part of my project anyway, only part of
Borland's Demo.
>
>> So here is the thing I am stuck on. How do I replace a local bool
>> with an external one which will use the client's existing connection?
>
> You don't.
>
OK... I think I see where your going with this but...
>> ( and accept new connections )
>
> That is handled automatically by COM for you. Every time
> TTestEventsImplImpl is instantiated, that instance represents a new client
> connection.
>
>> I can't figure out how to access Trigger() inside the Server Code at all
>
> Trigger() should be a public method of the TTestEventsImplImpl class.
> Given
> a pointer to a TTestEventsImplImpl instance, you can call Trigger() on it.
>
Yup I'll just bet I could too if ONLY:
>> let alone get an instance of it that has active connection(s) to the
> client(s).
>
> Simply keep a list of instantiated TTestEventsImplImpl instances. In
> TTestEventsImplImpl's constructor, add the 'this' pointer to the list. In
> the destructor, remove the 'this' pointer from the list. Then the server
> can loop through the list when needed.
>
I can get get tech support to explain how to get a list of instances if I
can get the rest figured out.
> TTestEventsImplImpl's constructor, add the 'this' pointer to the list
The help files say "this" is implied. What "type" is "this" I don't know.
I had less trouble learning to TALK than I'm having learning this.
Is this the list your talking about?? What should it look like when added?
Also there is no destructor. If I add one and ever refresh the type library
for some reason like adding new functions won't it vanish?
I'm not stupid but I feel that way right now.
class ATL_NO_VTABLE TTestEventsImplImpl :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<TTestEventsImplImpl, &CLSID_TestEventsImpl>,
public IConnectionPointContainerImpl<TTestEventsImplImpl>,
public TEvents_TestEventsImpl<TTestEventsImplImpl>,
public IDispatchImpl<ITestEventsImpl, &IID_ITestEventsImpl,
&LIBID_TestEventsTypeLib>
{
public:
TTestEventsImplImpl()
{
}
// Data used when registering Object
//
DECLARE_THREADING_MODEL(otApartment);
DECLARE_PROGID("TestEventsTypeLib.TestEventsImpl");
DECLARE_DESCRIPTION("");
// Function invoked to (un)register object
//
static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
{
TTypedComServerRegistrarT<TTestEventsImplImpl>
regObj(GetObjectCLSID(), GetProgID(), GetDescription());
return regObj.UpdateRegistry(bRegister);
}
BEGIN_COM_MAP(TTestEventsImplImpl)
COM_INTERFACE_ENTRY(ITestEventsImpl)
COM_INTERFACE_ENTRY2(IDispatch, ITestEventsImpl)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(TTestEventsImplImpl)
CONNECTION_POINT_ENTRY(DIID_ITestEventsImplEvents)
END_CONNECTION_POINT_MAP()
// ITestEventsImpl
public:
STDMETHOD(Trigger());
};
#endif //TestEventsImplImplH
Re: sockets????
Author: Remy Lebeau (TeamB)
Date: Mon, 31 Oct 2005 07:33
Date: Mon, 31 Oct 2005 07:33
48 lines
3146 bytes
3146 bytes
"Gary D" <gcdesroches@nctc.com> wrote in message news:4363f179$1@newsgroups.borland.com... > The help files say "this" is implied. Yes, but it can also be referenced explicitally as well. That is why the actual 'this' keyword exists at all. > What "type" is "this" I don't know. It is a compiler-provided pointer that is always the type of the class whose method is accessing the 'this' pointer. In other words, if 'this' is being used inside of TSomeClass::DoSomething(), then 'this' is of type TSomeClass. > Is this the list your talking about?? No. I am referring about a user-defined list, such as a TList or TThreadList object, that is managed in code and holds pointers to active Impl classs instances. > What should it look like when added? For example: http://groups.google.com/group/borland.public.cppbuilder.activex/msg/5cd00c5861a2be90?hl=en& You can read the following discussion for more details about why I use the above-linked code: http://groups.google.com/groups?as_q=tthreadlist&num=10&scoring=r&hl=en&as_epq=&as_oq=&as_eq=&as_ugroup=*activex*&as_usubject=&as_uauthors=remy+lebeau&lr=&as_drrb=q&as_qdr=&as_mind=1&as_minm=1&as_miny=1981&as_maxd=30&as_maxm=10&as_maxy=2005&safe=off > Also there is no destructor. Yes, there is. Every class has a destructor, just like every class has a constructor. If one is not provided in code, the compiler provides a default one implicitally. The code can declare an explicit one to override the default one. > If I add one and ever refresh the type library for some reason > like adding new functions won't it vanish? No. Refreshing the type library does not recreate the entire Impl files, only the TLB files. The refresh will append/remove the particular changes from the Impl files, but will otherwise leave any user-defined code alone. Gambit
Re: sockets????
Author: Gary D
Date: Tue, 01 Nov 2005 02:33
Date: Tue, 01 Nov 2005 02:33
43 lines
2744 bytes
2744 bytes
I added the code for the TTheadList and got it to compile without a problem.
I still can not call Trigger(); from the server side.
It IS public as you said but it is part of the COM class which I am
assuminig
means I need to have an instance of the class on the server side to be able
to
access Trigger() from. MyClass->Trigger(); ??
I can get instances of the Implementation but get access violations if I try
to
use it or the server will just lock up. calling Trigger() outside the class
will simply not compile. I get not a member errors etc. I looked at the
client side and see that there is this:
FEventSink.OnEvent1 = OnEvent1;
FEventSink.Connect(FTestEventsImpl);
but I don't know how it works, if I need it on the server side
or how to set it up if I do need it.
My forehead is bleeding from beating it against the wall.
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:4363be5e$1@newsgroups.borland.com...
>
> "Gary D" <gcdesroches@nctc.com> wrote in message
> news:436367ef$1@newsgroups.borland.com...
>
>> This is the code that creates a server connection and fires the event
>
> And? Does it actually work for you?
>
>> PLEASE, can you tell me what to do to get the server to
>> fire the OnEvent1 of the client when the SERVER wants
>> to and not because the client asked?
>
> I already told you earlier what to do on the server side - call the
> Fire_...() method for the event wheverever you want to.
>
>
> Gambit
>
>
Re: sockets????
Author: Remy Lebeau (TeamB)
Date: Tue, 01 Nov 2005 06:46
Date: Tue, 01 Nov 2005 06:46
52 lines
3584 bytes
3584 bytes
"Gary D" <gcdesroches@nctc.com> wrote in message news:4366d403@newsgroups.borland.com... > I added the code for the TTheadList and got it to compile > without a problem. I still can not call Trigger(); from the server side. Then you are still not using it properly. Please show your actual code. This is not that hard to implement. I've already given you the pieces for it. And I know it works because I use it all the time in my own COM servers. > It IS public as you said but it is part of the COM class which I am > assuminig means I need to have an instance of the class on the > server side to be able to access Trigger() from. MyClass->Trigger(); ?? Of course you do, and you do have such an instance available. Everytime the COM object is instantiated by a client, an instance of your class is created on the server side. That is the whole purpose of the list code I gave you - so that your server code has access to all active instances of the class. > I can get instances of the Implementation but get access violations if I > try to use it or the server will just lock up. Then you re not using it correctly. > calling Trigger() outside the class will simply not compile. > I get not a member errors etc. Then you are not accessing it correctly. > I looked at the client side and see that there is this: > > FEventSink.OnEvent1 = OnEvent1; > FEventSink.Connect(FTestEventsImpl); > > but I don't know how it works You did not read the articles I pointed you to, did you? The client's Sink is implemented in terms of the IConnectionPoint interface. Connect() queries the COM object for the IConnectionPointContainer interface, and from that then obtains the IConnectionPoint interface for your events. The client then calls IConnectionPoint::Advise(), which psses an IDuspatch interface to your server. On the server side, every time you call one of the Fire_...() methods, the client's IDispatch::Invoke() method is called, specifying the ID and parameters of the fired event. All of this is handled transparently for you. The only thing you have to concern yourself with in your own code is connecting the Sink to the client side object, and then calling the desired Fire_...() methods on the server side. Gambit
Re: sockets????
Author: Gary D
Date: Tue, 01 Nov 2005 23:08
Date: Tue, 01 Nov 2005 23:08
86 lines
4140 bytes
4140 bytes
Here is the TestEventsImplImpl.cpp File as modified to add your code:
I will Follow this with another message or 2 showing the rest of the files
you need to see.
// TESTEVENTSIMPLIMPL : Implementation of TTestEventsImplImpl (CoClass:
TestEventsImpl, Interface: ITestEventsImpl)
#include <vcl.h>
#pragma hdrstop
#include "TESTEVENTSIMPLIMPL.H"
#include "frmServer.h"
/////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
TThreadList* TTestEventsImplImpl::InterfaceList = NULL; // Code added from
newsgroup info
//---------------------------------------------------------------------------
TTestEventsImplImpl::TTestEventsImplImpl() // Function Def added from
newsgroup info
{
if(!InterfaceList)
InterfaceList = new TThreadList;
if(InterfaceList)
InterfaceList->Add(this);
}
//---------------------------------------------------------------------------
TTestEventsImplImpl::~TTestEventsImplImpl() // Function Def added from
newsgroup info
{
if(InterfaceList)
{
TList *list = InterfaceList->LockList();
int index = list->IndexOf(this);
if(index > -1)
list->Delete(index);
int count = list->Count;
InterfaceList->UnlockList();
if(count < 1)
{
delete InterfaceList;
InterfaceList = NULL;
}
}
}
//---------------------------------------------------------------------------
// TTestEventsImplImpl
STDMETHODIMP TTestEventsImplImpl::Trigger() // Existing
Function
{
WideString strName; // Existing Code
TTestEventsImplImpl *pIntf = NULL; // Code added
from newsgroup info
TList *list = InterfaceList->LockList(); // Code added
from newsgroup info
for(int x = 0; x < list->Count; x++) // Code added
from newsgroup info
{
try // Code added
from newsgroup info
{
pIntf = (TTestEventsImplImpl *)list->Items[x]; // Code added
from newsgroup info
if(pIntf) // Code added
from newsgroup info
pIntf->Fire_Event1(&strName); // Code Modified
from newsgroup info
}
catch(...) { } // Code added
from newsgroup info
}
InterfaceList->UnlockList(); // Code added
from newsgroup info
// Fire_Event1(strName); // Existing
Code
return S_OK; // Existing Code
}
//---------------------------------------------------------------------------
Re: sockets????
Author: Gary D
Date: Tue, 01 Nov 2005 23:09
Date: Tue, 01 Nov 2005 23:09
75 lines
3543 bytes
3543 bytes
This is the Header file
// TESTEVENTSIMPLIMPL.H : Declaration of the TTestEventsImplImpl
#ifndef TestEventsImplImplH
#define TestEventsImplImplH
#define ATL_APARTMENT_THREADED
#include "TestEventsTypeLib_TLB.h"
/////////////////////////////////////////////////////////////////////////////
// TTestEventsImplImpl Implements ITestEventsImpl, default interface of
TestEventsImpl
// and ITestEventsImplEvents, the default source interface
// ThreadingModel : Apartment
// Dual Interface : TRUE
// Event Support : TRUE
// Default ProgID : Project1.TestEventsImpl
// Description :
/////////////////////////////////////////////////////////////////////////////
class ATL_NO_VTABLE TTestEventsImplImpl :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<TTestEventsImplImpl, &CLSID_TestEventsImpl>,
public IConnectionPointContainerImpl<TTestEventsImplImpl>,
public TEvents_TestEventsImpl<TTestEventsImplImpl>,
public IDispatchImpl<ITestEventsImpl, &IID_ITestEventsImpl,
&LIBID_TestEventsTypeLib>
{
public:
// InterfaceList keeps a list of active client connections so the server
can
// fire an event(s) in each connection every time
static TThreadList *InterfaceList; // Code added from newsgroup
info
TTestEventsImplImpl(); // Existing Code ( Funtion was
empty )
~TTestEventsImplImpl(); // Code added from newsgroup
info
// Data used when registering Object
//
DECLARE_THREADING_MODEL(otApartment);
DECLARE_PROGID("TestEventsTypeLib.TestEventsImpl");
DECLARE_DESCRIPTION("");
// Function invoked to (un)register object
//
static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
{
TTypedComServerRegistrarT<TTestEventsImplImpl>
regObj(GetObjectCLSID(), GetProgID(), GetDescription());
return regObj.UpdateRegistry(bRegister);
}
BEGIN_COM_MAP(TTestEventsImplImpl)
COM_INTERFACE_ENTRY(ITestEventsImpl)
COM_INTERFACE_ENTRY2(IDispatch, ITestEventsImpl)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(TTestEventsImplImpl)
CONNECTION_POINT_ENTRY(DIID_ITestEventsImplEvents)
END_CONNECTION_POINT_MAP()
// ITestEventsImpl
public:
STDMETHOD(Trigger());
};
#endif //TestEventsImplImplH
Re: sockets????
Author: Gary D
Date: Tue, 01 Nov 2005 23:16
Date: Tue, 01 Nov 2005 23:16
30 lines
2429 bytes
2429 bytes
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
Here is how I am trying to fire the Trigger event.
Code completion opens a window showing Trigger() as available when I
type TestEventsImplImpl->
so what stupid thing am I doing?
#include "frmServer.h"
#include "TestEventsImplImpl.h"
#include "TestEventsTypeLib_TLB.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TServerWin *ServerWin;
TTestEventsImplImpl *TestEventsImplImpl;
//---------------------------------------------------------------------------
__fastcall TServerWin::TServerWin(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TServerWin::Button1Click(TObject *Sender)
{
TestEventsImplImpl->Trigger(); // This gets an access violation when
executed
}
//---------------------------------------------------------------------------
Re: sockets????
Author: Bob Gonder
Date: Wed, 02 Nov 2005 03:22
Date: Wed, 02 Nov 2005 03:22
9 lines
1502 bytes
1502 bytes
Gary D wrote: >TTestEventsImplImpl *TestEventsImplImpl; TestEventsImplImpl doesn't point to anything, so access violation is right. > TestEventsImplImpl->Trigger(); // This gets an access violation when >executed
Re: sockets????
Author: Remy Lebeau (TeamB)
Date: Wed, 02 Nov 2005 08:59
Date: Wed, 02 Nov 2005 08:59
12 lines
1555 bytes
1555 bytes
"Gary D" <gcdesroches@nctc.com> wrote in message news:4367f76b@newsgroups.borland.com... > TestEventsImplImpl->Trigger(); > This gets an access violation when executed Of course it does. You are calling Trigger() on an uninitialized pointer. You have not instantiated the TestEventsImplImpl class at all. Gambit
Re: sockets????
Author: Remy Lebeau (TeamB)
Date: Wed, 02 Nov 2005 09:04
Date: Wed, 02 Nov 2005 09:04
140 lines
5249 bytes
5249 bytes
"Gary D" <gcdesroches@nctc.com> wrote in message
news:4367f582@newsgroups.borland.com...
> Here is the TestEventsImplImpl.cpp File as modified to add your code:
You are going about it all wrong. Your Trigger() code should not be using
the TThreadList at all, unless you want clients to broadcast events to other
clients. The rest of the server code should be using the TThreadList to
reach the Fire_...() methods for each individual client.
Try this code instead:
class ATL_NO_VTABLE TTestEventsImplImpl :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<TTestEventsImplImpl, &CLSID_TestEventsImpl>,
public IConnectionPointContainerImpl<TTestEventsImplImpl>,
public TEvents_TestEventsImpl<TTestEventsImplImpl>,
public IDispatchImpl<ITestEventsImpl, &IID_ITestEventsImpl,
&LIBID_TestEventsTypeLib>
{
public:
static TThreadList* InterfaceList;
TTestEventsImplImpl();
~TTestEventsImplImpl();
// Data used when registering Object
//
DECLARE_THREADING_MODEL(otApartment);
DECLARE_PROGID("TestEventsTypeLib.TestEventsImpl");
DECLARE_DESCRIPTION("");
// Function invoked to (un)register object
//
static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
{
TTypedComServerRegistrarT<TTestEventsImplImpl>
regObj(GetObjectCLSID(), GetProgID(), GetDescription());
return regObj.UpdateRegistry(bRegister);
}
BEGIN_COM_MAP(TTestEventsImplImpl)
COM_INTERFACE_ENTRY(ITestEventsImpl)
COM_INTERFACE_ENTRY2(IDispatch, ITestEventsImpl)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(TTestEventsImplImpl)
CONNECTION_POINT_ENTRY(DIID_ITestEventsImplEvents)
END_CONNECTION_POINT_MAP()
public:
static void TriggerOnAllClients();
// ITestEventsImpl
public:
STDMETHOD(Trigger());
};
TThreadList* TTestEventsImplImpl::InterfaceList = NULL;
TTestEventsImplImpl::TTestEventsImplImpl()
{
if( !InterfaceList )
InterfaceList = new TThreadList;
if( InterfaceList )
InterfaceList->Add(this);
}
TTestEventsImplImpl::~TTestEventsImplImpl()
{
if( InterfaceList )
{
int count;
TList *list = InterfaceList->LockList();
try
{
list->Remove(this);
count = list->Count;
}
__finally {
InterfaceList->UnlockList();
}
if( count < 1 )
{
delete InterfaceList;
InterfaceList = NULL;
}
}
}
void TTestEventsImplImpl::TriggerOnAllClients()
{
if( InterfaceList )
{
TList *list = InterfaceList->LockList();
try
{
for(int x = 0; x < list->Count; ++x)
{
try
{
TTestEventsImplImpl *pIntf = (TTestEventsImplImpl *)
list->Items[x];
if( pIntf )
pIntf->Trigger();
}
catch(...) { }
}
}
__finally {
InterfaceList->UnlockList();
}
}
}
STDMETHODIMP TTestEventsImplImpl::Trigger()
{
WideString strName(L"Whatever");
Fire_Event1(strName);
return S_OK;
}
You can then do the following where desired in the server code:
void TCOMServerCode::DoSomething()
{
// ...
if( something happened )
TTestEventsImplImpl::TriggerOnAllClients();
// ...
}
Gambit
Re: sockets????
Author: Gary D
Date: Wed, 02 Nov 2005 11:26
Date: Wed, 02 Nov 2005 11:26
37 lines
2295 bytes
2295 bytes
I heard the heavenly choir sing this morning, from the server side. Thanks, Now that I have a working model I will be able to pick it apart and learn how it works. For one thing I have never seen this done as a means of executing a function: TTestEventsImplImpl::TriggerOnAllClients(); All I have ever seen is stuff like this: TTestEventsImplImpl->TriggerOnAllClients(); TTestEventsImplImpl.TriggerOnAllClients(); What are the differences between the 3 if it isn't to involved to explain? Gary "Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message news:43688124$1@newsgroups.borland.com... > > "Gary D" <gcdesroches@nctc.com> wrote in message > news:4367f76b@newsgroups.borland.com... > >> TestEventsImplImpl->Trigger(); >> This gets an access violation when executed > > Of course it does. You are calling Trigger() on an uninitialized pointer. > You have not instantiated the TestEventsImplImpl class at all. > > > Gambit > >
Re: sockets????
Author: Remy Lebeau (TeamB)
Date: Wed, 02 Nov 2005 18:21
Date: Wed, 02 Nov 2005 18:21
22 lines
2162 bytes
2162 bytes
"Gary D" <gcdesroches@nctc.com> wrote in message news:4368a28c$1@newsgroups.borland.com... > For one thing I have never seen this done as a means of > executing a function: > > TTestEventsImplImpl::TriggerOnAllClients(); TriggerOnAllClients() is declared as a 'static' method. That allows it to be called using just the class type without any pointer to an instance of the class. > What are the differences between the 3 if it isn't to involved to explain? The '->' and '.' operators operate on class instances. The '.' operator can only be invoked on the memory of an object instance directly, whereas the '->' operator is invoked on a pointer to an object instance (or an object that overrides the '->' operator, but that is a separate issue). Gambit
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads