Тип очереди в канале
Я установил kannel из пакета rpm kannel-sw-1.4.3.3-6.rh5u3. Выполните простые тесты, такие как отправка одного за другим пяти сообщений ("1", "2", "3", "4" и "5") в smsbox через http get для обработки ошибки регулирования. Со стороны SMSC пропускная способность составила 2 SMS в минуту. Я ожидал получить смс в следующем порядке: "1" "2" "3" "4" "5" Но в журналах канала и дампе SMPP я получил поток, подобный следующему:
> "1"
< ok
> "2"
< ok
> "3"
< throttling error
#first timeout less than 1 minute according config
> "4"
< throttling error
#second timeout less than 1 minute according config, but in sum with first more than 1 minute
> "5"
< ok
> "3"
< ok
> "4"
< throttling error
and so on
Таким образом, порядок в результате был "1", "2", "5", "3", "4" вместо "1", "2", "3", "4", "5". Можно ли изменить тип заказа при попытке отправить последнее сообщение об ошибке вместо следующего в цепочке? В документации я нашел опцию sms-coming-queue-limit. Но я понятия не имею, что означает "Значение 0 означает предоставление строгого приоритета исходящим сообщениям", и, к сожалению, я не могу запустить тесты в ближайшее время. Что такое строгий приоритет и как насчет очереди \ типа заказа?
Большое спасибо.
2 ответа
Мой предыдущий ответ был неверным. Правильный ответ:
Изменить функцию
sms_priority_compare
вsms.c
:if (msg1->sms.time > msg2->sms.time) ret = 1; else if (msg1->sms.time < msg2->sms.time) ret = -1;
в
if (msg1->sms.time > msg2->sms.time) ret = -1; else if (msg1->sms.time < msg2->sms.time) ret = 1; else { if (msg1->sms.id > msg2->sms.id) ret = -1; else if (msg1->sms.id < msg2->sms.id) ret = 1; else ret = 0; }
Изменить функцию
smpp_status_to_smscconn_failure_reason
вsmsc/smsc_smpp.c
:static long smpp_status_to_smscconn_failure_reason(long status) { switch(status) { case SMPP_ESME_RMSGQFUL: case SMPP_ESME_RTHROTTLED: case SMPP_ESME_RX_T_APPN: case SMPP_ESME_RSYSERR: return SMSCCONN_FAILED_TEMPORARILY; break; default: return SMSCCONN_FAILED_REJECTED; } }
в
static long smpp_status_to_smscconn_failure_reason(long status) { switch(status) { case SMPP_ESME_RMSGQFUL: case SMPP_ESME_RX_T_APPN: case SMPP_ESME_RSYSERR: return SMSCCONN_FAILED_TEMPORARILY; break; case SMPP_ESME_RTHROTTLED: return SMPP_ESME_RTHROTTLED; break; default: return SMSCCONN_FAILED_REJECTED; } }
Изменить функцию
handle_pdu
вsmsc/smsc_smpp.c
(case submit_sm_resp:
):if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED) time(&(smpp->throttling_err_time)); else smpp->throttling_err_time = 0; bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("0x%08lx/%s", pdu->u.submit_sm_resp.command_status, smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
в
if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED) time(&(smpp->throttling_err_time)); else smpp->throttling_err_time = 0; if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RMSGQFUL) time(&msg->sms.time); bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("0x%08lx/%s", pdu->u.submit_sm_resp.command_status, smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
Изменить функцию
bb_smscconn_send_failed
вbb_smscconn.c
:case SMSCCONN_FAILED_TEMPORARILY: ... gwlist_produce(outgoing_sms, sms); break; case SMSCCONN_FAILED_SHUTDOWN: gwlist_produce(outgoing_sms, sms); break;
в
case SMSCCONN_FAILED_TEMPORARILY: ... gwlist_produce(outgoing_sms, sms); break; case SMPP_ESME_RTHROTTLED: gwlist_insert(outgoing_sms, 0, sms); break; case SMSCCONN_FAILED_SHUTDOWN: gwlist_produce(outgoing_sms, sms); break;
Изменить функцию
handle_split
вbb_smscconn.c
:case SMSCCONN_FAILED_TEMPORARILY: ... gwlist_produce(outgoing_sms, msg); break; case SMSCCONN_FAILED_DISCARDED:
в
case SMSCCONN_FAILED_TEMPORARILY: ... gwlist_produce(outgoing_sms, msg); break; case SMPP_ESME_RTHROTTLED: gwlist_insert(outgoing_sms, 0, msg); break; case SMSCCONN_FAILED_DISCARDED:
Обработка ошибок регулирования SMPP:
I did the following patch to smsc/smsc_smpp.c in "case submit_sm_resp:"
section from line 1609:
change
***
if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED)
time(&(smpp->throttling_err_time));
else
smpp->throttling_err_time = 0;
bb_smscconn_send_failed(smpp->conn, msg, reason, octstr_format("0x%08lx/%s",
pdu->u.submit_sm_resp.command_status,
smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
***
to
***
if (pdu->u.submit_sm_resp.command_status == SMPP_ESME_RTHROTTLED) {
time(&(smpp->throttling_err_time));
/* Put the message back into the SMPP queue */
gw_prioqueue_produce(smpp->msgs_to_send, msg);
} else {
smpp->throttling_err_time = 0;
bb_smscconn_send_failed(smpp->conn, msg, reason,
octstr_format("0x%08lx/%s", pdu->u.submit_sm_resp.command_status,
smpp_error_to_string(pdu->u.submit_sm_resp.command_status)));
}
***
and in sms.c I have changed the function sms_priority_compare() to reverse
time sorting order (for some reason it was LIFO):
if (msg1->sms.time > msg2->sms.time)
ret = -1;
else if (msg1->sms.time < msg2->sms.time)
ret = 1;
-------------- next part --------------
Заказ составных СМС-частей основан на дополнительном сравнении их sms.id
:
int sms_priority_compare(const void *a, const void *b)
{
int ret;
Msg *msg1 = (Msg*)a, *msg2 = (Msg*)b;
gw_assert(msg_type(msg1) == sms);
gw_assert(msg_type(msg2) == sms);
if (msg1->sms.priority > msg2->sms.priority)
ret = 1;
else if (msg1->sms.priority < msg2->sms.priority)
ret = -1;
else {
if (msg1->sms.time > msg2->sms.time)
ret = -1;
else if (msg1->sms.time < msg2->sms.time)
ret = 1;
else {
if (msg1->sms.id > msg2->sms.id)
ret = -1;
else if (msg1->sms.id < msg2->sms.id)
ret = 1;
else
ret = 0;
}
}
return ret;
}