On Wed, 2016-10-05 at 04:46 -0700, Tobias Duckworth wrote: > Thanks Robbie, > > Didn't realise I am on the wrong list, sorry about that. > > OK, so comparing what I see in a non connection_engine build to a > connection_engine one. > > From the Wireshark traces of both I can see that in the > connection_engine > build the Azure end is sending empty (presumably heartbeat) frames > every 70 > seconds, but the qpid-proton end is never sending any (although it > does > respond to the Azure ones). > > On the non connection_engine build both ends are sending periodic > empty > frames - The qpid-proton ones are every 120 seconds, which is half > the > idle_timeout specified in the connect packets coming from Azure. > > So it looks like I need to convince the connection_engine to send out > heartbeat frames and it will be fixed.
Correct. I just fixed this in the Go binding, you need to call pn_transport_tick(pn_connnection_engine_transport(eng)) periodically and it will take care of heartbeats for you. I am working on a C "driver" framework with a C example (using the libuv library) to show everything that needs to be done in a complete proton driver. Meanwhile the Go code is model you can translate to C. Basically you need to call pn_transport_tick when there is a PN_TRANSPORT event (starts the first tick, and many anounce changes to the tick schedule) and also ticks chain - each call to tick returns a time to call it again. Here's an annotated explanation, notes with XX: // Let proton run timed activity and set up the next tick func (eng *Engine) tick() { now := time.Now() // XX Gets current time. // XX pn_timestamp_t next = pn_transport_tick(pn_connection_engine_transport(eng)); next := eng.Transport().Tick(now) // XX if (next != 0) { if !next.IsZero() { // Set some timer mechanism to fire at time `next`, // In Go we subtract now from next to get a relative time. eng.timer.Reset(next.Sub(now)) } } func (eng *Engine) dispatch() bool { var needTick bool // Set if we need to tick the transport. for { cevent := C.pn_connection_engine_dispatch(&eng.engine) if cevent == nil { break } event := makeEvent(cevent, eng) if event.Type() == ETransport { needTick = true } for _, h := range eng.handlers { h.HandleEvent(event) } } if needTick { eng.tick() } return !bool(C.pn_connection_engine_finished(&eng.engine)) } The Go IO loop monitors the timer as well as read/write IO and calls dispatch() if it fires. Should be easy to translate into C, but you will need to add some scheduled wakeup to your poller or whatever you are using for IO. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@qpid.apache.org For additional commands, e-mail: dev-h...@qpid.apache.org