int mosquitto_unsubscribe(struct mosquitto *mosq, int *mid, const char *sub) { if(!mosq) return MOSQ_ERR_INVAL; if(mosq->sock == INVALID_SOCKET) return MOSQ_ERR_NO_CONN; return _mosquitto_send_unsubscribe(mosq, mid, false, sub); }
/* 整个.c文件就是处理客户端的连接请求,返回一个连接确认包 */ int mqtt3_handle_connack(struct mosquitto_db *db, struct mosquitto *context) { uint8_t byte; uint8_t rc; int i; char *notification_topic; int notification_topic_len; char notification_payload; if(!context){ return MOSQ_ERR_INVAL; } #ifdef WITH_STRICT_PROTOCOL if(context->in_packet.remaining_length != 2){ return MOSQ_ERR_PROTOCOL; } #endif _mosquitto_log_printf(NULL, MOSQ_LOG_DEBUG, "Received CONNACK on connection %s.", context->id); if(_mosquitto_read_byte(&context->in_packet, &byte)) return 1; // Reserved byte, not used if(_mosquitto_read_byte(&context->in_packet, &rc)) return 1; switch(rc){ // case CONNACK_ACCEPTED: // 这是一个broker客户端 if(context->bridge){ // 提醒机制是怎么做的? if(context->bridge->notifications){ notification_payload = '1'; if(context->bridge->notification_topic){ if(_mosquitto_send_real_publish(context, _mosquitto_mid_generate(context), context->bridge->notification_topic, 1, ¬ification_payload, 1, true, 0)){ return 1; } mqtt3_db_messages_easy_queue(db, context, context->bridge->notification_topic, 1, 1, ¬ification_payload, 1); }else{ notification_topic_len = strlen(context->id)+strlen("$SYS/broker/connection//state"); notification_topic = _mosquitto_malloc(sizeof(char)*(notification_topic_len+1)); if(!notification_topic) return MOSQ_ERR_NOMEM; snprintf(notification_topic, notification_topic_len+1, "$SYS/broker/connection/%s/state", context->id); notification_payload = '1'; if(_mosquitto_send_real_publish(context, _mosquitto_mid_generate(context), notification_topic, 1, ¬ification_payload, 1, true, 0)){ _mosquitto_free(notification_topic); return 1; } mqtt3_db_messages_easy_queue(db, context, notification_topic, 1, 1, ¬ification_payload, 1); _mosquitto_free(notification_topic); } }// end of bridge notifications // broker之间的订阅处理机制,画个图可能好理解点 for(i=0; i<context->bridge->topic_count; i++){ if(context->bridge->topics[i].direction == bd_in || context->bridge->topics[i].direction == bd_both){ if(_mosquitto_send_subscribe(context, NULL, false, context->bridge->topics[i].remote_topic, context->bridge->topics[i].qos)){ return 1; } }else{ if(_mosquitto_send_unsubscribe(context, NULL, false, context->bridge->topics[i].remote_topic)){ /* direction = inwards only. This means we should not be subscribed * to the topic. It is possible that we used to be subscribed to * this topic so unsubscribe. */ return 1; } } } } // 原来更新的是客户端的额状态 context->state = mosq_cs_connected; return MOSQ_ERR_SUCCESS; // 连接错误,版本问题 case CONNACK_REFUSED_PROTOCOL_VERSION: if(context->bridge){ context->bridge->try_private_accepted = false; } _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: unacceptable protocol version"); return 1; // case CONNACK_REFUSED_IDENTIFIER_REJECTED: _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: identifier rejected"); return 1; // case CONNACK_REFUSED_SERVER_UNAVAILABLE: _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: broker unavailable"); return 1; // case CONNACK_REFUSED_BAD_USERNAME_PASSWORD: _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: broker unavailable"); return 1; // case CONNACK_REFUSED_NOT_AUTHORIZED: _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: not authorised"); return 1; // default: _mosquitto_log_printf(NULL, MOSQ_LOG_ERR, "Connection Refused: unknown reason"); return 1; } return 1; }