Kannel DLR配置疑问:boxc字段为空及dlr-url配置求助
Kannel DLR问题解决方案
一、/dlr-url 配置内容、文件位置及示例代码
dlr-url是Kannel收到短信状态报告(DLR)后,主动发起HTTP请求的回调接口,你得搭个简单的Web服务接住这个请求,处理Kannel传过来的短信状态参数(比如是否送达、终端状态、短信ID等)。
1. 核心要求
- 得是Kannel能连通的HTTP/HTTPS地址(你的配置是
http://192.168.252.222/dlr-url,要确保这个地址对应的服务能正常访问) - 支持接收GET/POST请求(Kannel默认用GET,可在
kannel.conf里改dlr-method换POST) - 逻辑上至少要把Kannel传的参数存到你的MySQL
dlr表,方便后续判断短信状态
2. 文件位置
根据你用的Web服务器,把代码放到对应根目录:
- Apache(Linux):
/var/www/html/;Windows:C:\Apache24\htdocs\ - Nginx(Linux):
/usr/share/nginx/html/;Windows:C:\nginx\html\ - 比如你存成
dlr-url.php,那dlr-url就得改成http://192.168.252.222/dlr-url.php,要和配置里的地址完全对应
3. 示例代码
示例1:PHP版(无需额外依赖,适合新手)
创建dlr-url.php,替换里面的数据库信息:
<?php // 接收Kannel传的DLR参数 $smsc = $_GET['smsc'] ?? ''; $id = $_GET['id'] ?? ''; $dlr_status = $_GET['dlr-status'] ?? ''; // 关键状态码:比如0=送达,2=终端关机 $phone = $_GET['phone'] ?? ''; $boxc = $_GET['boxc'] ?? ''; // 对应你dlr表的boxc字段 // 连接你的MySQL(替换成自己的数据库账号、密码、库名) $conn = mysqli_connect('localhost', 'db_user', 'db_password', 'db_name'); if (!$conn) { die('数据库连不上:' . mysqli_connect_error()); } // 把数据插入dlr表(确保表字段和这里对应) $sql = "INSERT INTO dlr (smsc, id, dlr_status, phone, boxc) VALUES ('$smsc', '$id', '$dlr_status', '$phone', '$boxc')"; if (mysqli_query($conn, $sql)) { echo '状态已保存'; } else { echo '出错了:' . mysqli_error($conn); } mysqli_close($conn); ?>
示例2:Python Flask版(轻量Web服务)
- 先装Flask:
pip install flask - 创建
dlr_url.py,替换数据库信息:
from flask import Flask, request import mysql.connector app = Flask(__name__) @app.route('/dlr-url', methods=['GET']) def save_dlr(): # 拿Kannel传的参数 smsc = request.args.get('smsc', '') id = request.args.get('id', '') dlr_status = request.args.get('dlr-status', '') phone = request.args.get('phone', '') boxc = request.args.get('boxc', '') # 连数据库 conn = mysql.connector.connect( host='localhost', user='db_user', password='db_password', database='db_name' ) cursor = conn.cursor() # 插入数据 sql = """INSERT INTO dlr (smsc, id, dlr_status, phone, boxc) VALUES (%s, %s, %s, %s, %s)""" cursor.execute(sql, (smsc, id, dlr_status, phone, boxc)) conn.commit() cursor.close() conn.close() return '收到状态报告' if __name__ == '__main__': app.run(host='0.0.0.0', port=80) # 启动服务,监听所有IP的80端口
运行服务:python dlr_url.py,此时http://192.168.252.222/dlr-url就能正常访问了
二、dlr表boxc为空、sent_sms和send_sms表无数据的原因排查
1. boxc字段为空的原因
- Kannel没传这个参数:检查
kannel.conf和sqlbox.conf,确认sqlbox模块正常加载,且配置里的group、id对应正确 - 回调接口没处理这个参数:看你写的dlr-url代码,有没有接收
boxc参数并插入到数据库(参考上面的示例代码) - 短信中心没返回该字段:有些短信中心(SMSC)的DLR里不带boxc信息,去看Kannel的
bearerbox.log,查DLR请求的参数列表,确认有没有boxc字段
2. sent_sms和send_sms表无数据的原因
- 没开sqlbox存储:检查
kannel.conf里有没有加storage = sqlbox,以及group = sqlbox的配置是否正确 - sqlbox连不上数据库:看
sqlbox.log日志,有没有数据库密码错误、权限不够、表结构不匹配的报错 - 发短信时没指定存储参数:调用Kannel发送接口时,必须传
dlr-mask(比如dlr-mask=31表示请求所有状态报告),同时确认kannel.conf里开了store-sms配置 - 表结构不符合要求:Kannel的sent_sms、send_sms有固定字段要求,比如sent_sms需要
id, smsc, ts, destination等,send_sms需要id, smsc, status等,检查你的表结构是不是和官方要求一致 - sqlbox进程没跑起来:用
ps aux | grep sqlbox查进程,确认sqlbox服务正常启动
内容的提问来源于stack exchange,提问作者sicora
相关产品推荐
相关产品推荐

