opensips添加离线消息功能

2024-04-25 09:08
文章标签 功能 消息 离线 opensips

本文主要是介绍opensips添加离线消息功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

按照项目的需求,需要使用OpenSIPS的离线功能,现在将配置过程记录以备后用。

OpenSIPS离线消息功能依赖于msilo模块(http://www.opensips.org/html/docs/modules/1.11.x/msilo.html)


修改OpenSIPS的配置文件opensips.cfg添加

loadmodule "msilo.so"
#加载msilo模块
modparam("msilo", "db_table", "silo")
#配置离线消息存储的表silo
modparam("msilo", "db_url","mysql://opensips:opensipsrw@localhost/opensips")
#配置数据库路径
modparam("msilo", "add_date", 1)
#配置是否显示[offline message +时间]
modparam("msilo","content_type_hdr","Content-Type: text/plain\r\n")
#配置存储类型

配置路由部分:

#注释以下这段:
/*      if ( !(is_method("REGISTER")  ) ) {if (from_uri==myself){# authenticate if from local subscriber# authenticate all initial non-REGISTER request that pretend to be# generated by local subscriber (domain from FROM URI is local)if (!proxy_authorize("", "subscriber")) {proxy_challenge("", "0");exit;}if (!db_check_from()) {sl_send_reply("403","Forbidden auth ID");exit;}consume_credentials();# caller authenticated} else {# if caller is not local, then called number must be localif (!uri==myself) {send_reply("403","Rely forbidden");exit;}}}
*/#修改一下这段if (is_method("REGISTER")){# authenticate the REGISTER requestsif (!www_authorize("", "subscriber")){www_challenge("", "0");exit;}if (!db_check_to()){sl_send_reply("403","Forbidden auth ID");exit;}if (   0 ) setflag(TCP_PERSISTENT);if (!save("location"))sl_reply_error();#增加部分--startif (m_dump()){log("MSILO:offline message dumped\n");}else{log("MSILO:no offline message dumped\n");}#增加部分--endexit;}#修改这段if (!lookup("location","m")) {if (!db_does_uri_exist()) {send_reply("420","Bad Extension");exit;}#从这里开始修改if(! t_newtran()){sl_reply_error();exit;}#以下为增加部分if (!method=="MESSAGE"){if (!t_reply("404", "Not found")){sl_reply_error();};exit;};log("MSILO:Message received -> storing using MSILO\n");if (m_store("$ru")){log("MSILO:offline message stored\n");if (!t_reply("202","Accepted")){sl_reply_error();};}else{log("MSILO:offline message NOT stroed\n");if(!t_reply("503","Service Unavailable")){sl_reply_error();};};exit;}t_on_failure("1");   #增加这句if (isbflagset(NAT)) setflag(NAT);   #在配置文件最后增加:
failure_route[1] {# forwarding failed -- check if the request was a MESSAGEif (!method=="MESSAGE"){exit;};log(1,"MSILO:the downstream UA doesn‘t support MESSAGEs\n");# we have changed the R-URI with the contact address, ignore it nowif (m_store("$ou")){log("MSILO: offline message stored\n");t_reply("202", "Accepted");}else{log("MSILO: offline message NOT stored\n");t_reply("503", "Service Unavailable");};
}

到这里离线消息功能配置完成,为方便其他朋友,特意贴出全部配置文件(注意红色部分)

#
# $Id$
#
# OpenSIPS residential configuration script
#     by OpenSIPS Solutions <team@opensips-solutions.com>
#
# This script was generated via "make menuconfig", from
#   the "Residential" scenario.
# You can enable / disable more features / functionalities by
#   re-generating the scenario with different options.#
#
# Please refer to the Core CookBook at:
#      http://www.opensips.org/Resources/DocsCookbooks
# for a explanation of possible statements, functions and parameters.
#


####### Global Parameters #########

debug=3
log_stderror=no
log_facility=LOG_LOCAL0

fork=yes
children=4

/* uncomment the following lines to enable debugging */
#debug=6
#fork=no
#log_stderror=yes

/* uncomment the next line to enable the auto temporary blacklisting of 
   not available destinations (default disabled) */
#disable_dns_blacklist=no

/* uncomment the next line to enable IPv6 lookup after IPv4 dns 
   lookup failures (default disabled) */
#dns_try_ipv6=yes

/* comment the next line to enable the auto discovery of local aliases
   based on revers DNS on IPs */
auto_aliases=no


listen=udp:eth0:5060   # CUSTOMIZE ME


#disable_tcp=yes

#disable_tls=yes


####### Modules Section ########

#set module path
mpath="/data/opensips1.11.4/lib64/opensips/modules/"

#### SIGNALING module
loadmodule "signaling.so"

#### StateLess module
loadmodule "sl.so"

#### Transaction Module
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)
modparam("tm", "restart_fr_on_each_reply", 0)
modparam("tm", "onreply_avp_mode", 1)

#### Record Route Module
loadmodule "rr.so"
/* do not append from tag to the RR (no need for this script) */
modparam("rr", "append_fromtag", 0)

#### MAX ForWarD module
loadmodule "maxfwd.so"

#### SIP MSG OPerationS module
loadmodule "sipmsgops.so"

#### FIFO Management Interface
loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)


#### URI module
loadmodule "uri.so"
modparam("uri", "use_uri_table", 0)
modparam("uri", "db_url","mysql://opensips:opensipsrw@localhost/opensips")


loadmodule "msilo.so"
modparam("msilo", "db_table", "silo")
modparam("msilo", "db_url","mysql://opensips:opensipsrw@localhost/opensips")
modparam("msilo", "add_date", 1)
modparam("msilo","content_type_hdr","Content-Type: text/plain\r\n")






#### MYSQL module
loadmodule "db_mysql.so"



#### USeR LOCation module
loadmodule "usrloc.so"
modparam("usrloc", "nat_bflag", "NAT")
modparam("usrloc", "db_mode",   2)
modparam("usrloc", "db_url",
    "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME


#### REGISTRAR module
loadmodule "registrar.so"
modparam("registrar", "tcp_persistent_flag", "TCP_PERSISTENT")
modparam("registrar", "received_avp", "$avp(received_nh)")
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)

#### ACCounting module
loadmodule "acc.so"
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_cancels", 0)
/* by default we do not adjust the direct of the sequential requests.
   if you enable this parameter, be sure the enable "append_fromtag"
   in "rr" module */
modparam("acc", "detect_direction", 0)
modparam("acc", "failed_transaction_flag", "ACC_FAILED")
/* account triggers (flags) */
modparam("acc", "db_flag", "ACC_DO")
modparam("acc", "db_missed_flag", "ACC_MISSED")
modparam("acc", "db_url",
    "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME


#### AUTHentication modules
loadmodule "auth.so"
loadmodule "auth_db.so"
modparam("auth_db", "calculate_ha1", no)
modparam("auth_db", "password_column", "ha1")
modparam("auth_db", "db_url",
    "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME
modparam("auth_db", "load_credentials", "")


#### ALIAS module
loadmodule "alias_db.so"
modparam("alias_db", "db_url",
    "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME






#### DIALOG module
loadmodule "dialog.so"
modparam("dialog", "dlg_match_mode", 1)
modparam("dialog", "default_timeout", 21600)  # 6 hours timeout
modparam("dialog", "db_mode", 2)
modparam("dialog", "db_url",
    "mysql://opensips:opensipsrw@localhost/opensips") # CUSTOMIZE ME


####  NAT modules
loadmodule "nathelper.so"
modparam("nathelper", "natping_interval", 10)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "received_avp", "$avp(received_nh)")

loadmodule "rtpproxy.so"
modparam("rtpproxy", "rtpproxy_sock", "udp:localhost:12221") # CUSTOMIZE ME








####### Routing Logic ########

# main request routing logic

route{
    force_rport();
    if (nat_uac_test("23")) {
        if (is_method("REGISTER")) {
            fix_nated_register();
            setbflag(NAT);
        } else {
            fix_nated_contact();
            setflag(NAT);
        }
    }
     

    if (!mf_process_maxfwd_header("10")) {
        sl_send_reply("483","Too Many Hops");
        exit;
    }

    if (has_totag()) {
        # sequential request withing a dialog should
        # take the path determined by record-routing
        if (loose_route()) {
            
            # validate the sequential request against dialog
            if ( $DLG_status!=NULL && !validate_dialog() ) {
                xlog("In-Dialog $rm from $si (callid=$ci) is not valid according to dialog\n");
                ## exit;
            }
            
            if (is_method("BYE")) {
                setflag(ACC_DO); # do accounting ...
                setflag(ACC_FAILED); # ... even if the transaction fails
            } else if (is_method("INVITE")) {
                # even if in most of the cases is useless, do RR for
                # re-INVITEs alos, as some buggy clients do change route set
                # during the dialog.
                record_route();
            }

            if (check_route_param("nat=yes")) 
                setflag(NAT);

            # route it out to whatever destination was set by loose_route()
            # in $du (destination URI).
            route(relay);
        } else {
            
            if ( is_method("ACK") ) {
                if ( t_check_trans() ) {
                    # non loose-route, but stateful ACK; must be an ACK after 
                    # a 487 or e.g. 404 from upstream server
                    t_relay();
                    exit;
                } else {
                    # ACK without matching transaction ->
                    # ignore and discard
                    exit;
                }
            }
            sl_send_reply("404","Not here");
        }
        exit;
    }

    # CANCEL processing
    if (is_method("CANCEL"))
    {
        if (t_check_trans())
            t_relay();
        exit;
    }

    t_check_trans();

/*    if ( !(is_method("REGISTER")  ) ) {
        
        if (from_uri==myself)
        
        {
            
            # authenticate if from local subscriber
            # authenticate all initial non-REGISTER request that pretend to be
            # generated by local subscriber (domain from FROM URI is local)
            if (!proxy_authorize("", "subscriber")) {
                proxy_challenge("", "0");
                exit;
            }
            if (!db_check_from()) {
                sl_send_reply("403","Forbidden auth ID");
                exit;
            }
        
            consume_credentials();
            # caller authenticated

            
        } else {
            # if caller is not local, then called number must be local
            
            if (!uri==myself) {
                send_reply("403","Rely forbidden");
                exit;
            }
        }

    }

*/

    # preloaded route checking
    if (loose_route()) {
        xlog("L_ERR",
        "Attempt to route with preloaded Route‘s [$fu/$tu/$ru/$ci]");
        if (!is_method("ACK"))
            sl_send_reply("403","Preload Route denied");
        exit;
    }

    # record routing
    if (!is_method("REGISTER|MESSAGE"))
        record_route();

    # account only INVITEs
    if (is_method("INVITE")) {
        
        # create dialog with timeout
        if ( !create_dialog("B") ) {
            send_reply("500","Internal Server Error");
            exit;
        }
        
        setflag(ACC_DO); # do accounting
    }

    
    if (!uri==myself) {
        append_hf("P-hint: outbound\r\n"); 
        
        route(relay);
    }

    # requests for my domain
    
    if (is_method("PUBLISH|SUBSCRIBE"))
    {
        sl_send_reply("503", "Service Unavailable");
        exit;
    }

    if (is_method("REGISTER"))
    {
        
        # authenticate the REGISTER requests
        if (!www_authorize("", "subscriber"))
        {
            www_challenge("", "0");
            exit;
        }
        
        if (!db_check_to()) 
        {
            sl_send_reply("403","Forbidden auth ID");
            exit;
        }

        if (   0 ) setflag(TCP_PERSISTENT);

        if (!save("location"))
            sl_reply_error();

                if (m_dump()){
                        log("MSILO:offline message dumped\n");
                }else{
                        log("MSILO:no offline message dumped\n");
                }


        exit;
    }

    if ($rU==NULL) {
        # request with no Username in RURI
        sl_send_reply("484","Address Incomplete");
        exit;
    }

    
    # apply DB based aliases
    alias_db_lookup("dbaliases");

    

     

    # do lookup with method filtering
    if (!lookup("location","m")) {
        if (!db_does_uri_exist()) {
            send_reply("420","Bad Extension");
            exit;
        }
        

        if(! t_newtran()){
            sl_reply_error();
            exit;
        }
        if (!method=="MESSAGE")
        {
                    if (!t_reply("404", "Not found")) 
                    {
                            sl_reply_error();
                       };
                    exit;
                };
        log("MSILO:Message received -> storing using MSILO\n");
        if (m_store("$ru")){
            log("MSILO:offline message stored\n");
            if (!t_reply("202","Accepted")){
                sl_reply_error();
            };
        }else{
            log("MSILO:offline message NOT stroed\n");
            if(!t_reply("503","Service Unavailable")){
                sl_reply_error();
            };
        };
        exit;
    } 

    t_on_failure("1");
    if (isbflagset(NAT)) setflag(NAT);

    # when routing via usrloc, log the missed calls also
    setflag(ACC_MISSED);
    route(relay);
}


route[relay] {
    # for INVITEs enable some additional helper routes
    if (is_method("INVITE")) {
        
        if (isflagset(NAT)) {
            rtpproxy_offer("ro");
        }

        t_on_branch("per_branch_ops");
        t_on_reply("handle_nat");
        t_on_failure("missed_call");
    }

    if (isflagset(NAT)) {
        add_rr_param(";nat=yes");
        }

    if (!t_relay()) {
        send_reply("500","Internal Error");
    };
    exit;
}




branch_route[per_branch_ops] {
    xlog("new branch at $ru\n");
}


onreply_route[handle_nat] {
    if (nat_uac_test("1"))
        fix_nated_contact();
    if ( isflagset(NAT) )
        rtpproxy_answer("ro");
    xlog("incoming reply\n");
}


failure_route[missed_call] {
    if (t_was_cancelled()) {
        exit;
    }

    # uncomment the following lines if you want to block client 
    # redirect based on 3xx replies.
    ##if (t_check_status("3[0-9][0-9]")) {
    ##t_reply("404","Not found");
    ##    exit;
    ##}

    
}



local_route {
    if (is_method("BYE") && $DLG_dir=="UPSTREAM") {
        
        acc_db_request("200 Dialog Timeout", "acc");
        
    }
}

failure_route[1] {
    # forwarding failed -- check if the request was a MESSAGE 
    if (!method=="MESSAGE")
    {
        exit;
    };
    
    log(1,"MSILO:the downstream UA doesn‘t support MESSAGEs\n");
    # we have changed the R-URI with the contact address, ignore it now
    if (m_store("$ou"))
    {
        log("MSILO: offline message stored\n");
        t_reply("202", "Accepted"); 
    }else{
        log("MSILO: offline message NOT stored\n");
        t_reply("503", "Service Unavailable");
    };
}

这篇关于opensips添加离线消息功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/934250

相关文章

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

Spring+MyBatis+jeasyui 功能树列表

java代码@EnablePaging@RequestMapping(value = "/queryFunctionList.html")@ResponseBodypublic Map<String, Object> queryFunctionList() {String parentId = "";List<FunctionDisplay> tables = query(parent

ActiveMQ—消息特性(延迟和定时消息投递)

ActiveMQ消息特性:延迟和定时消息投递(Delay and Schedule Message Delivery) 转自:http://blog.csdn.net/kimmking/article/details/8443872 有时候我们不希望消息马上被broker投递出去,而是想要消息60秒以后发给消费者,或者我们想让消息没隔一定时间投递一次,一共投递指定的次数。。。 类似

PostgreSQL核心功能特性与使用领域及场景分析

PostgreSQL有什么优点? 开源和免费 PostgreSQL是一个开源的数据库管理系统,可以免费使用和修改。这降低了企业的成本,并为开发者提供了一个活跃的社区和丰富的资源。 高度兼容 PostgreSQL支持多种操作系统(如Linux、Windows、macOS等)和编程语言(如C、C++、Java、Python、Ruby等),并提供了多种接口(如JDBC、ODBC、ADO.NET等

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

nginx介绍及常用功能

什么是nginx nginx跟Apache一样,是一个web服务器(网站服务器),通过HTTP协议提供各种网络服务。 Apache:重量级的,不支持高并发的服务器。在Apache上运行数以万计的并发访问,会导致服务器消耗大量内存。操作系统对其进行进程或线程间的切换也消耗了大量的CPU资源,导致HTTP请求的平均响应速度降低。这些都决定了Apache不可能成为高性能WEB服务器  nginx: