@@ -13,18 +13,6 @@ import (
1313 "github.com/plgd-dev/go-coap/v2/udp/message/pool"
1414)
1515
16- //Observation represents subscription to resource on the server
17- type Observation struct {
18- token message.Token
19- path string
20- obsSequence uint32
21- etag []byte
22- cc * ClientConn
23- lastEvent time.Time
24-
25- mutex sync.Mutex
26- }
27-
2816func NewObservationHandler (obsertionTokenHandler * HandlerContainer , next HandlerFunc ) HandlerFunc {
2917 return func (w * ResponseWriter , r * pool.Message ) {
3018 v , err := obsertionTokenHandler .Get (r .Token ())
@@ -41,6 +29,34 @@ func NewObservationHandler(obsertionTokenHandler *HandlerContainer, next Handler
4129 }
4230}
4331
32+ //Observation represents subscription to resource on the server
33+ type Observation struct {
34+ token message.Token
35+ path string
36+ cc * ClientConn
37+ observeFunc func (req * pool.Message )
38+ respCodeChan chan codes.Code
39+
40+ obsSequence uint32
41+ etag []byte
42+ lastEvent time.Time
43+ mutex sync.Mutex
44+
45+ waitForReponse uint32
46+ }
47+
48+ func newObservation (token message.Token , path string , cc * ClientConn , observeFunc func (req * pool.Message ), respCodeChan chan codes.Code ) * Observation {
49+ return & Observation {
50+ token : token ,
51+ path : path ,
52+ obsSequence : 0 ,
53+ cc : cc ,
54+ waitForReponse : 1 ,
55+ respCodeChan : respCodeChan ,
56+ observeFunc : observeFunc ,
57+ }
58+ }
59+
4460func (o * Observation ) cleanUp () {
4561 o .cc .observationTokenHandler .Pop (o .token )
4662 registeredRequest , ok := o .cc .observationRequests .PullOut (o .token .String ())
@@ -49,6 +65,20 @@ func (o *Observation) cleanUp() {
4965 }
5066}
5167
68+ func (o * Observation ) handler (w * ResponseWriter , r * pool.Message ) {
69+ code := r .Code ()
70+ if atomic .CompareAndSwapUint32 (& o .waitForReponse , 1 , 0 ) {
71+ select {
72+ case o .respCodeChan <- code :
73+ default :
74+ }
75+ o .respCodeChan = nil
76+ }
77+ if o .wantBeNotified (r ) {
78+ o .observeFunc (r )
79+ }
80+ }
81+
5282// Cancel remove observation from server. For recreate observation use Observe.
5383func (o * Observation ) Cancel (ctx context.Context ) error {
5484 o .cleanUp ()
@@ -97,27 +127,11 @@ func (cc *ClientConn) Observe(ctx context.Context, path string, observeFunc func
97127 }
98128 token := req .Token ()
99129 req .SetObserve (0 )
100- o := & Observation {
101- token : token ,
102- path : path ,
103- obsSequence : 0 ,
104- cc : cc ,
105- }
106130 respCodeChan := make (chan codes.Code , 1 )
107- waitForReponse := uint32 (1 )
131+ o := newObservation (token , path , cc , observeFunc , respCodeChan )
132+
108133 cc .observationRequests .Store (token .String (), req )
109- err = o .cc .observationTokenHandler .Insert (token .String (), func (w * ResponseWriter , r * pool.Message ) {
110- code := r .Code ()
111- if atomic .CompareAndSwapUint32 (& waitForReponse , 1 , 0 ) {
112- select {
113- case respCodeChan <- code :
114- default :
115- }
116- }
117- if o .wantBeNotified (r ) {
118- observeFunc (r )
119- }
120- })
134+ err = o .cc .observationTokenHandler .Insert (token .String (), o .handler )
121135 defer func (err * error ) {
122136 if * err != nil {
123137 o .cleanUp ()
0 commit comments