void QMQTT::ClientPrivate::onNetworkConnected() { Q_Q(Client); sendConnect(); startKeepAlive(); emit q->connected(); }
void startServer() { state = ServerStarting; startKeepAlive(); refreshTimeout(); update(); }
void handle(const ZhttpResponsePacket &packet) { if(state == ClientRequestStartWait) { if(packet.from.isEmpty()) { state = Stopped; errored = true; errorCondition = ErrorGeneric; cleanup(); log_warning("zhttp client: error id=%s initial ack for streamed input request did not contain from field", packet.id.data()); emit q->error(); return; } toAddress = packet.from; state = ClientRequesting; startKeepAlive(); } else if(state == ClientRequestFinishWait) { toAddress = packet.from; state = ClientReceiving; if(!doReq) startKeepAlive(); } if(packet.type == ZhttpResponsePacket::Error) { errored = true; errorCondition = convertError(packet.condition); log_debug("zhttp client: error id=%s cond=%s", packet.id.data(), packet.condition.data()); state = Stopped; cleanup(); emit q->error(); return; } else if(packet.type == ZhttpResponsePacket::Cancel) { log_debug("zhttp client: received cancel id=%s", packet.id.data()); errored = true; errorCondition = ErrorGeneric; state = Stopped; cleanup(); emit q->error(); return; } // if non-req mode, check sequencing if(!doReq && packet.seq != inSeq) { log_warning("zhttp client: error id=%s received message out of sequence, canceling", packet.id.data()); // if this was not an error packet, send cancel if(packet.type != ZhttpResponsePacket::Error && packet.type != ZhttpResponsePacket::Cancel) { ZhttpRequestPacket p; p.type = ZhttpRequestPacket::Cancel; writePacket(p); } state = Stopped; errored = true; errorCondition = ErrorGeneric; cleanup(); emit q->error(); return; } ++inSeq; refreshTimeout(); if(doReq && (packet.type != ZhttpResponsePacket::Data || packet.more)) { log_warning("zhttp/zws client req: received invalid req response"); state = Stopped; errored = true; errorCondition = ErrorGeneric; cleanup(); emit q->error(); return; } if(packet.type == ZhttpResponsePacket::Data) { if(!haveResponseValues) { haveResponseValues = true; responseCode = packet.code; responseReason = packet.reason; responseHeaders = packet.headers; } if(doReq) { if(responseBodyBuf.size() + packet.body.size() > REQ_BUF_MAX) log_warning("zhttp client req: id=%s server response too large", packet.id.data()); } else { if(responseBodyBuf.size() + packet.body.size() > IDEAL_CREDITS) log_warning("zhttp client: id=%s server is sending too fast", packet.id.data()); } responseBodyBuf += packet.body; if(!doReq && packet.credits > 0) { outCredits += packet.credits; if(outCredits > 0) { // try to write anything that was waiting on credits QPointer<QObject> self = this; tryWrite(); if(!self) return; } } if(packet.more) { if(!packet.body.isEmpty()) emit q->readyRead(); } else { // always emit readyRead here even if body is empty, for EOF state = Stopped; cleanup(); emit q->readyRead(); } } else if(packet.type == ZhttpResponsePacket::Credit) { if(packet.credits > 0) { outCredits += packet.credits; if(outCredits > 0) tryWrite(); } } else if(packet.type == ZhttpResponsePacket::KeepAlive) { // nothing to do } else { log_debug("zhttp client: unsupported packet type id=%s type=%d", packet.id.data(), (int)packet.type); } }
void QMQTT::ClientPrivate::onNetworkConnected() { sendConnect(); startKeepAlive(); }
void handle(const ZhttpResponsePacket &packet) { if(packet.type == ZhttpResponsePacket::Error) { errorCondition = convertError(packet.condition); log_debug("zws client: error id=%s cond=%s", packet.id.data(), packet.condition.data()); responseCode = packet.code; responseReason = packet.reason; responseHeaders = packet.headers; responseBody = packet.body; state = Idle; cleanup(); emit q->error(); return; } else if(packet.type == ZhttpResponsePacket::Cancel) { log_debug("zws client: received cancel id=%s", packet.id.data()); errorCondition = ErrorGeneric; state = Idle; cleanup(); emit q->error(); return; } if(!packet.from.isEmpty()) toAddress = packet.from; if(packet.seq != inSeq) { log_warning("zws client: error id=%s received message out of sequence, canceling", packet.id.data()); tryRespondCancel(packet); state = Idle; errorCondition = ErrorGeneric; cleanup(); emit q->error(); return; } if(!toAddress.isEmpty() && !keepAliveTimer->isActive()) startKeepAlive(); ++inSeq; refreshTimeout(); if(state == Connecting) { if(packet.type != ZhttpResponsePacket::Data && packet.type != ZhttpResponsePacket::Credit && packet.type != ZhttpResponsePacket::KeepAlive) { state = Idle; errorCondition = ErrorGeneric; cleanup(); log_warning("zws client: error id=%s initial response wrong type", packet.id.data()); emit q->error(); return; } if(packet.from.isEmpty()) { state = Idle; errorCondition = ErrorGeneric; cleanup(); log_warning("zws client: error id=%s initial ack did not contain from field", packet.id.data()); emit q->error(); return; } } if(packet.type == ZhttpResponsePacket::Data || packet.type == ZhttpResponsePacket::Ping || packet.type == ZhttpResponsePacket::Pong) { if(state == Connecting) { // this is assured earlier assert(packet.type == ZhttpResponsePacket::Data); responseCode = packet.code; responseReason = packet.reason; responseHeaders = packet.headers; if(packet.credits > 0) outCredits += packet.credits; state = Connected; update(); emit q->connected(); } else { if(inSize + packet.body.size() > IDEAL_CREDITS) log_warning("zws client: id=%s server is sending too fast", packet.id.data()); if(packet.type == ZhttpResponsePacket::Data) { handleIncomingDataPacket(packet.contentType, packet.body, packet.more); } else if(packet.type == ZhttpResponsePacket::Ping) { inFrames += Frame(Frame::Ping, packet.body, false); inSize += packet.body.size(); } else if(packet.type == ZhttpResponsePacket::Pong) { inFrames += Frame(Frame::Pong, packet.body, false); inSize += packet.body.size(); } if(packet.credits > 0) { outCredits += packet.credits; if(outCredits > 0) { // try to write anything that was waiting on credits QPointer<QObject> self = this; tryWrite(); if(!self) return; } } emit q->readyRead(); } } else if(packet.type == ZhttpResponsePacket::Close) { handlePeerClose(packet.code); } else if(packet.type == ZhttpResponsePacket::Credit) { if(packet.credits > 0) { outCredits += packet.credits; if(outCredits > 0) tryWrite(); } } else if(packet.type == ZhttpResponsePacket::KeepAlive) { // nothing to do } else { log_debug("zws client: unsupported packet type id=%s type=%d", packet.id.data(), (int)packet.type); } }