Presentasjon lastes. Vennligst vent

Presentasjon lastes. Vennligst vent

Connection Points i COM Bakgrunn Begrunnelse Bruk.

Liknende presentasjoner


Presentasjon om: "Connection Points i COM Bakgrunn Begrunnelse Bruk."— Utskrift av presentasjonen:

1 Connection Points i COM Bakgrunn Begrunnelse Bruk

2 Oversikt over foredrag 4 Observer pattern –Bruk –Begrunnelse –Variasjoner 4 Løsninger i COM –Advise sinks –Connection Points Begrunnelse + oversikt Bruk

3 Noen forutsetninger 4 Relativt god kjennskap til COM –IUnknown –IDispatch –Formål og bruk (løs kobling mellom klient og tjener, transpartent distribuering) –IEnumXXX interfaces

4 Bakgrunn - Observer 4 Observer er et av “Patterns” som er beskrevet i Gamma, et al “Design Patterns” [GOF] 4 Fra Design Patterns: –“Intent: Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.” 4 Det vil si: Vi ønsker et design der noen objekter (Observers) ønsker å bli informert når “ting skjer” med et annet object (Subject)

5 Observer - 2 (Arkitektur) 4 Observer har følgende design oversikt i “Design Patterns”:

6 Observer - 3 (Bruk) 4 Sekvensdiagram:

7 Observer - 4 (Eksempler) 4 Forhold mellom brukergrensesnitt og “modell” –Gir mulighet for bruk flere klienter mot samme state uten unødvendig kommunikasjonsoverhead 4 Brukes i Microsoft’s “Document-View” arkitektur, og i den eldre (og bedre) “Controller- Model-View” arkitekturen. 4 Kan med fordel brukes i distribuerte systemer.

8 Observer - 5 Varianter 4 Flere Subjects, Observers, og Events. –Kan modifiseres med et “Subscription” object –Kan “flates ut” for bruk i f.eks. C. Dette minner endel om Windows’ “WindowProc” 4 Asynkron oppdatering –Egen(e) tråd(er) for å la Subject oppdatere Observers 4 Informasjon om state kan sendes med Update 4 Flere varianter til “Update” funksjonen

9 COM og Observer 4 Observer patternet egner seg godt for distribuert og/eller modulbasert bruk –Mulighet for asynkron oppdatering –Løs kobling (“coupling”) mellom klient og tjener

10 COM og Observers - Problemer 4 Hvordan kan en scripting klient/dynamisk klient finne ut Run Time hvilke “Observer” interfaces en “Subject” støtter 4 Hvordan vil COM’s identitetregler fungere med Detach? (Jeg vet ikke)

11 COM Observer 1: Advise Sink 4 Den enkleste måten å lage en form for toveis kommunikasjon mellom klient og tjener 4 Eksempel: [ uuid(…), object, pointer_default(unique) ] interface IAdviseSink : IUnknown { HRESULT StateIsChanged(IAdviseSource* pSource); }; [ uuid(…), object, pointer_default(unique) ] interface IAdviseSource : IUnknown { HRESULT Attach(IAdviceSink* pSink); HRESULT Detach(IAdviceSink* pSink); // … + metoder for å endre tilstanden til objektet }; [ uuid(…) ] coclass AdviseSource { [default] interface IAdviseSource; };

12 Advise Sink - Bruk 4 Lag en klasse som implementerer IAdviseSink 4 Kall Subject’s IAdviseSource::Subscribe 4 IAdviseSink::StateIsChanged vil bli kalt fra subject når nødvendig 4 Før klientens Advise Sink slettes, kall IAdviseSource::Unsubscribe class MyAdviseSink : public IAdviseSink { public: MyAdviseSink(IAdviseSource* pSource) : m_pSource(pSource) { m_pSource->Attach(this); } ~MyAdviseSink() { m_pSource->Detach(this); } STDMETHOD(StateIsChanged)(IAdviseSink*) { ::MessageBox(NULL, ”Server state has changed”, ””, MB_OK); } private: CComPtr m_pSource; }; JMB: Det kan hevdes at det ikke er så lurt å gjøre Attach og Detach i Constructoren og destructoren, ettersom disse funksjonene ikke er gode til å håntere feil situasjoner. JMB: Det kan hevdes at det ikke er så lurt å gjøre Attach og Detach i Constructoren og destructoren, ettersom disse funksjonene ikke er gode til å håntere feil situasjoner.

13 COM Observer 2: Connection Points (endelig!) 4 Formålet med å bruke Connection Points over Advise Sinks er hovedsaklig å gi støtte for Script klienter, og for å gi en dynamisk (run time) mulighet for å finne ut hvilke “observers” et objekt støtter. 4 Problemer som bør nevnes: –Mer komplisert enn Advise Sinks. –“Unødvendige” kall gir performance hit med distribuert klient/tjener.

14 Connection Points - Interfaces 4 IConnectionPointContainer 4 IEnumConnectionPoints 4 IConnectionPoint 4 IEnumConnections 4 I tilfellet med Advise Sinks er det vi som implementerer denne funksjonaliteten.

15 Connection points - Arkitektur

16 Connection Points - Arkitektur 2 4 En server kan ha flere connection points. 4 En klient kan implementere flere Sources.

17 IConnectionPointContainer [ object, uuid(…), pointer_default(unique) ] interface IConnectionPointContainer : IUnknown { HRESULT EnumConnectionPoints ( [out] IEnumConnectionPoints ** ppEnum ); HRESULT FindConnectionPoint ( [in] REFIID riid, [out] IConnectionPoint ** ppCP ); };

18 IEnumConnectionPoints [ object, uuid(...), pointer_default(unique) ] interface IEnumConnectionPoints : IUnknown { [local] HRESULT Next( [in] ULONG cConnections, [out, size_is(cConnections), length_is(*pcFetched)] IConnectionPoint** ppCP, [out] ULONG * pcFetched ); [call_as(Next)] HRESULT RemoteNext( [in] ULONG cConnections, [out, size_is(cConnections), length_is(*pcFetched)] IConnectionPoint** ppCP, [out] ULONG * pcFetched ); HRESULT Skip( [in] ULONG cConnections ); HRESULT Reset(); HRESULT Clone( [out] IEnumConnectionPoints ** ppEnum ); };

19 IConnectionPoint [ object, uuid(...), pointer_default(unique) ] interface IConnectionPoint : IUnknown { HRESULT GetConnectionInterface( [out] IID * pIID ); HRESULT GetConnectionPointContainer( [out] IConnectionPointContainer ** ppCPC ); HRESULT Advise( [in] IUnknown * pUnkSink, [out] DWORD * pdwCookie ); HRESULT Unadvise( [in] DWORD dwCookie ); HRESULT EnumConnections( [out] IEnumConnections ** ppEnum ); };

20 IEnumConnections [ object, uuid(…), pointer_default(unique) ] interface IEnumConnections : IUnknown { typedef struct tagCONNECTDATA { IUnknown * pUnk; DWORD dwCookie; } CONNECTDATA; [local]HRESULT Next( [in] ULONG cConnections, [out, size_is(cConnections), length_is(*pcFetched)] CONNECTDATA* rgcd, [out] ULONG * pcFetched ); [call_as(Next)] HRESULT RemoteNext( [in] ULONG cConnections, [out, size_is(cConnections), length_is(*pcFetched)] LPCONNECTDATA rgcd, [out] ULONG * pcFetched ); HRESULT Skip([in] ULONG cConnections); HRESULT Reset(); HRESULT Clone([out] IEnumConnections ** ppEnum); };

21 Connection Points - Eksempel [ uuid(…), object, dual, pointer_default(unique) ] interface IAdviseSink : IDispatch { HRESULT StateIsChanged(IAdviceSource* pSource); }; [ uuid(…), object, dual, pointer_default(unique) ] interface IAdviseSource : IDispatch { … }; [ uuid(…) ] coclass AdviseSource { [default] interface IAdviseSource; [default, source] interface IAdviseSink; interface IConnectionPointContainer; };

22 Connection points og Advise Sinks - Forskjeller 4 Både klient og tjener interface er Dispatch 4 IAdviseSource’s metoder for registrering og avregistrering er fjernet (Implementert i IConnectionPointContainer med venner)

23 Connection Points - C++ klient 4 Klient har implementert et objekt med IAdviseSink, og har en peker til en AdviseSource (coclass) DWORD Connect(IAdviseSource* pSource, IAdviseSink *pSink) { CComPtr pCPC; pSource->QueryInterface(__uuidof(IConnectionPointContainer), &pCPC); CComPtr pCP; pCPC->FindConnectionPoint(__uuidof(IAdviseSink), &pCP); DWORD dwCookie; pCP->Advice(pSink, &dwCookie); return dwCookie; }

24 Connection points - Vurderinger 1  Endel lenger enn AdviseSink tilfellet (ville være en linje: pSource->Subscribe(pSink); ) 4 QueryInterface, FindConnectionPoint og Advice fører alle til kall over nettverket. 4 I implementasjonen av Advice (eller hver gang IAdviseSource::StateIsChanged kalles), må serveren kalle QueryInterface for å få riktig interface (Advice tar en IUnknown* som argument)

25 Connection points - Vurderinger 2 4 IConnectionPointContainer og IConnectionPoint gir mulighet til å finne ut mer informasjon dynamisk, f.eks. hvilke Source interfaces som støttes (gjennom IConnectionPointContainer::EnumConnecti onPoints og IConnectionPoint::EnumConnections)

26 Connection Points Implementasjon - Server 4 Implementasjon av Connection Points på en server er relativt smertefritt med bruk av ATL. (mk:@MSITStore: \VCMFC. CHM::/html/_atl_connection_points.htm) 4 ATL Wizard har støtte for connection points.

27 Connection Points Implementasjon - ATL class CoAdviseSource : public CComObjectRootEx, public CComCoClass, public IConnectionPointContainerImpl, public IConnectionPointImpl { public:... BEGIN_COM_MAP(CoAdviseSource) COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer) END_COM_MAP() BEGIN_CONNECTION_POINT_MAP(CoAdviseSource) CONNECTION_POINT_ENTRY(IID_IPropertyNotifySink) END_CONNECTION_POINT_MAP()... }; JMB: De uthevede linjene gjentas for hvert connection point som skal implementeres JMB: De uthevede linjene gjentas for hvert connection point som skal implementeres

28 Advise Sinks - Implementasjon class CoAdviseSource : public CComObjectRootEx, public CComCoClass { public:... BEGIN_COM_MAP(CoAdviseSource) COM_INTERFACE_ENTRY(IAdviseSource) END_COM_MAP() class CSourceImpl : public IAdviseSink { public: STDMETHOD(StateIsChanged)(IAdviseSource* pSource) { std::list ::iterator pSink = m_pSinkList.begin(); while ( pSink != m_pSinkList.end() ) (*pSink++)->StateIsChanged(pSource); return S_OK; } // … Implementasjon av Attach og Detach private: std::list m_pSinkList; } m_SourceImpl; STDMETHOD(Attach)(IAdviceSink* pSink); STDMETHOD(Detach)(IAdviceSink* pSink); }; JMB: Kaller inn til tilsvarende metode i CSourceImpl JMB: Kaller inn til tilsvarende metode i CSourceImpl

29 Advise Sink Implementasjon - sende event 4 IAdviseSink: { // … m_SourceImpl->StateIsChanged(this); }

30 Connection Points ATL Implementasjon - Sende event CComQIPtr pCPC(pUnk); if (!pCPC) return S_OK; CComPtr pCP; pCPC->FindConnectionPoint(IID_IAdviseSink, &pCP); if (!pCP) return S_OK; CComPtr pEnum; if (FAILED(pCP->EnumConnections(&pEnum))) return S_OK; CONNECTDATA cd; while (pEnum->Next(1, &cd, NULL) == S_OK) { if (cd.pUnk) { HRESULT hr = S_OK; CComQIPtr pSink(cd.pUnk); if (pSink) hr = pSink->StateIsChanged(dispID); cd.pUnk->Release(); if (hr == S_FALSE) return S_FALSE; } return S_OK; JMB: Denne koden er hentet fra CFirePropNotifyEvent::FireOnRequestEdit og redigert til vårt formål JMB: Denne koden er hentet fra CFirePropNotifyEvent::FireOnRequestEdit og redigert til vårt formål JMB: Koden er komplisert, ettersom den ønsker at serveren skal bruke klientens rammeverk. Det er mulig at det allerede finnes enklere måter å gjøre dette på. JMB: Koden er komplisert, ettersom den ønsker at serveren skal bruke klientens rammeverk. Det er mulig at det allerede finnes enklere måter å gjøre dette på.

31 Betraktninger 4 ATL gir endel kode gratis, men gir også endel kompleksitet (tidliger diskusjon) 4 Det er imidlertid mulig å ha både en ConnectionPoint og en AdviseSink implementasjon av Observer, nemlig: STDMETHODIMP(CoAdviseSource::Attach)(IAdviseSink* pSink, DWORD* pdwCookie) { typedef IConnectionPointImpl IAdviseSource; return ((IAdviseSource*)this)->Advise(pSink, pdwCookie); } JMB: Signaturen til Attach er modifisert med en Cookie for å ha en enklere mapping til connection points. JMB: Signaturen til Attach er modifisert med en Cookie for å ha en enklere mapping til connection points.

32 Noen merknader 4 Connection points vil antageligvis gjennomgå en større endring til COM+. For det meste gjennom endringer i C++ språket i VC++ (versjon 7?) 4 Advise Sinks går ann å bruke fra VB, men det krever mer arbeid enn Connection points. 4 Connection points er eneste muligheten fra script klienter. 4 Connection points og Advise Sinks er kompatible, i det minste dersom man lager sin egen implementasjon.

33 Oppsummering 4 Formålet med connection points er å åpne for to-veis kommunikasjon mellom klient og tjener i COM. 4 Den som implementerer tjeneren bestemmer Connection Point (Observer, Advise Sink) interfacet. 4 Connection points er en noe klønete og ineffektiv implementasjon av Observer Patternet i [GOF]. 4 Dersom man skal støtte script-klienter må man bruke Connection Points, eller er man fri til å bruke en egen løsning, som Advise Sinks. 4 ATL har en standard implementasjon av Connection Points. Den er imidlertid ikke helt perfekt.


Laste ned ppt "Connection Points i COM Bakgrunn Begrunnelse Bruk."

Liknende presentasjoner


Annonser fra Google