我已经从rpm软件包kannel-sw-1.4.3.3-6.rh5u3安装了kannel。做了一个简单的测试,例如通过http get向短信盒发送了五条消息("1","2","3","4"和"5")以处理限制错误。从 SMSC 端的吞吐量为每分钟 2 条短信。我希望按以下顺序收到短信:"1""2""3""4""5"但是在 kannel 日志和 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"。是否可以更改尝试发送上一条失败消息而不是链中的下一条失败消息的订单类型?在文档中,我发现了短信传入队列限制选项。但是我不知道"值 0 意味着严格优先考虑传出消息"是什么意思,不幸的是我无法很快运行测试。什么是严格优先级,队列\订单类型呢?
非常感谢。
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;
}
我之前的回答是错误的。直接回答:
-
更改
sms.c
中的功能sms_priority_compare
: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; }
-
更改
smsc/smsc_smpp.c
中的功能smpp_status_to_smscconn_failure_reason
: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; } }
-
更改
smsc/smsc_smpp.c
中的函数handle_pdu
(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.c
中的功能bb_smscconn_send_failed
: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;
-
更改
bb_smscconn.c
中的功能handle_split
: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: