Print
Category: OpenSIPS
Hits: 1597

OpenSIPS - Call Dispatcher

1. ในตอนนี้เราจะใช้ OpenSIPS กระจายสายที่เรียกเข้ามาไปยัง IssabelPBX จำนวน 3 servers โดยจะกระจายสายแบบ roundrobin

สามารถกำหนดน้ำหนักได้ ว่าจะให้ IssabelPBX ตัวไหนรับสายมากน้อย คอนฟิกนี้ใช้สำหรับ inbound call center ขนาดใหญ่ที่

ไม่สามารถใช้ IssabelPBX ตัวเดียวรองรับ traffic ทั้งหมดได้ 

 

 

จากรูป calls จาก voice gateway จะถูกส่งไปยัง OpenSIPS แล้ว OpenSIPS จะส่งต่อ calls เหล่านี้ไปยัง IssabelPBX ตัวที่หนึ่ง

สอง สาม ตามลำดับ ถ้า IssabelPBX ตัวไหนไม่ทำงาน OpenSIPS ก็ส่ง calls ไปยังตัวถัดไป

 

2. OpenSIPS คอนฟิกไฟล์ copy + paste คอนฟิกข้างล่างไปที่ /etc/opensips/opensips.cfg

 

###################################

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

###################################

 

log_level=3

log_stderror=no

log_facility=LOG_LOCAL0

 

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:192.168.10.222:5060

 

################################

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

################################

 

#set module path

mpath="/lib64/opensips/modules/"

 

#### SIGNALING module

loadmodule "signaling.so"

 

#### StateLess module

loadmodule "sl.so"

 

#### Permissions module

loadmodule "permissions.so"

modparam("permissions", "db_url",

        "mysql://opensips:opensipsrw@localhost/opensips")

 

#### 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)

 

#### MYSQL module

loadmodule "db_mysql.so"

 

#### AVPOPS module

loadmodule "avpops.so"

 

#### 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", "db_url",

        "mysql://opensips:opensipsrw@localhost/opensips")

 

#### DISPATCHER module

loadmodule "dispatcher.so"

modparam("dispatcher", "db_url",

        "mysql://opensips:opensipsrw@localhost/opensips")

modparam("dispatcher", "ds_ping_method", "OPTIONS")

modparam("dispatcher", "ds_probing_mode", 1)

modparam("dispatcher", "ds_ping_interval", 30)

 

#### MI_JSON module

loadmodule "mi_json.so"

modparam("mi_json", "mi_json_root", "json")

 

loadmodule "proto_udp.so"

 

#### HTTPD module

loadmodule "httpd.so"

modparam("httpd", "port", 8888)

 

##############################

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

##############################

 

# main request routing logic

 

route {

        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()) {

 

                        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();

                        }

 

                        # 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;

        }

 

        #### INITIAL REQUEST

 

        # CANCEL processing

        if (is_method("CANCEL")) {

                if (t_check_trans())

                        t_relay();

                exit;

        } else if (!is_method("INVITE")) {

                send_reply("405","Method Not Allowed");

                exit;

        }

 

        if ($rU==NULL) {

                # request with no Username in RURI

                sl_send_reply("484","Address Incomplete");

                exit;

        }

 

        t_check_trans();

 

        # check source ip address (just before preloaded route checking)

        if (!check_source_address("0")) {

                xlog("IP address is not allowed $fu");

                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

        record_route();

 

        setflag(ACC_DO); # do accounting

 

 

        if ( !ds_select_dst("1","4") ) {

 

                send_reply("500","No Destination available");

                exit;

        }

 

 

        t_on_failure("GW_FAILOVER");

 

        route(RELAY);

}

 

route[RELAY] {

        if (!t_relay()) {

                sl_reply_error();

        };

        exit;

}

 

failure_route[GW_FAILOVER] {

        if (t_was_cancelled()) {

                exit;

        }

 

        # failure detection with redirect to next available trunk

        if (t_check_status("(408)|([56][0-9][0-9])")) {

 

        if (t_check_status("(408)|([56][0-9][0-9])")) {

                xlog("Failed trunk $rd/$du detected \n");

 

 

                if ( ds_next_dst() ) {

 

                        t_on_failure("GW_FAILOVER");

                        t_relay();

                        exit;

                }

 

                send_reply("500","All GW are down");

        }

}

 

}

 

 

 

 

กำหนด Permissions module ให้รับ calls จาก voice gateway (ip = 192.168.10.3) เท่านั้น

 

 

กำหนด Dispatcher module ให้ส่ง calls ไป IssabelPBX ip 192.168.10.250 หรือ 192.168.10.251 หรือ 192.168.10.252

ตามรูปเรากำหนดน้ำหนักไว้เท่ากับ 1

 

3. คอนฟิกนี้สำหรับ inbound calls เท่านั้น ไม่สามารถโทรออกจาก IssabelPBX ⇒ OpenSIPS ⇒ ไปยัง voice gateway ได้

สามารถนำไปใช้ในกรณีที่เป็น inbound call center ที่มีจำนวน calls มากๆ