你可以通过Asterisk管理接口事件来获取活动呼叫的数量。

huangapple go评论76阅读模式
英文:

How can I get number of active calls from Asterisk Manager Interface Event

问题

我已经连接到了Asterisk,并成功从PeerStatus事件中获取到活动和非活动对等方的数量,但现在我需要获取活动呼叫和通道的数量并显示出来。我尝试了查找ChannelStateDesc=Up的方法,但它不起作用。即使我放置了日志,我也看不到找到该事件。我该如何修复它(也许使用CoreShowChannelsComplete事件)?提前谢谢。

//server.go
package server

import (
	"bufio"
	"fmt"
	"net"
	"strings"

	"data"
)

func ConnectToAMI(address, username, password string) error {
	conn, err := net.Dial("tcp", address)
	if err != nil {
		return err
	}
	defer conn.Close()

	fmt.Fprintf(conn, "Action: Login\r\nUsername: %s\r\nSecret: %s\r\n\r\n", username, password)

	peerStatus := &data.PeerStatus{}
	callStatus := &data.CallStatus{}

	scanner := bufio.NewScanner(conn)
	for scanner.Scan() {
		line := scanner.Text()
		fmt.Println(line)

		if strings.HasPrefix(line, "PeerStatus") {
			data.GetPeerStatus(line, peerStatus)
			fmt.Println("活动对等方数量:", peerStatus.Active)
			fmt.Println("非活动对等方数量:", peerStatus.Inactive)
		} else if strings.HasPrefix(line, "CoreShowChannel") {
			data.GetChannelStatus(line, callStatus)
			fmt.Println("活动呼叫数量:", callStatus.ActiveCalls)
			fmt.Println("活动通道数量:", callStatus.ActiveChannels)
		}

	}

	if err := scanner.Err(); err != nil {
		return err
	}

	return nil
}


//calls.go
package data

import (
	"encoding/json"
	"fmt"
	"strings"
)

type CallStatus struct {
	ActiveCalls    int `json:"active_calls"`
	ActiveChannels int `json:"active_channels"`
}

func (cs *CallStatus) UpdateCallStatus(state string) {
	fmt.Println("UpdateCallStatus函数", state)

	switch state {
	case "Up":
		cs.ActiveCalls++
		cs.ActiveChannels = cs.ActiveCalls * 2
	case "Down":
		cs.ActiveCalls--
		cs.ActiveChannels = cs.ActiveChannels - 2
	default:
	}
}

func GetChannelStatus(event string, callStatus *CallStatus) {
	fmt.Println("GetChannelStatus函数", event)
	for _, line := range strings.Split(event, "\r\n") {
		if strings.HasPrefix(line, "ChannelStateDesc: ") {
			state := strings.TrimSpace(strings.TrimPrefix(line, "ChannelStateDesc: "))
			callStatus.UpdateCallStatus(state)
		}
	}
}



英文:

I've made connection to asterisk, and managed to get number of active and inactive peers from event PeerStatus, but now i need to get number of active calls and channels and display them. I've tried method to look for ChannelStateDesc=Up but it doesn't work. Even when I put logs I don't see that the event is being found. How can i fix it (maybe with event CoreShowChannelsComplete?) Thanks in advance

//server.go
package server

import (
	"bufio"
	"fmt"
	"net"
	"strings"

	"data"
)

func ConnectToAMI(address, username, password string) error {
	conn, err := net.Dial("tcp", address)
	if err != nil {
		return err
	}
	defer conn.Close()

	fmt.Fprintf(conn, "Action: Login\r\nUsername: %s\r\nSecret: %s\r\n\r\n", username, password)

	peerStatus := &data.PeerStatus{}
	callStatus := &data.CallStatus{}

	scanner := bufio.NewScanner(conn)
	for scanner.Scan() {
		line := scanner.Text()
		fmt.Println(line)

		if strings.HasPrefix(line, "PeerStatus") {
			data.GetPeerStatus(line, peerStatus)
			fmt.Println("Active peers:", peerStatus.Active)
			fmt.Println("Inactive peers:", peerStatus.Inactive)
		} else if strings.HasPrefix(line, "CoreShowChannel") {
			data.GetChannelStatus(line, callStatus)
			fmt.Println("Active peers:", peerStatus.Active)
			fmt.Println("Inactive peers:", peerStatus.Inactive)
		}

	}

	if err := scanner.Err(); err != nil {
		return err
	}

	return nil
}


//calls.go
package data

import (
	"encoding/json"
	"fmt"
	"strings"
)

type CallStatus struct {
	ActiveCalls    int `json:"active_calls"`
	ActiveChannels int `json:"active_channels"`
}

func (cs *CallStatus) UpdateCallStatus(state string) {
	fmt.Println("UpdateCallStatus function", state)

	switch state {
	case "Up":
		cs.ActiveCalls++
		cs.ActiveChannels = cs.ActiveCalls * 2
	case "Down":
		cs.ActiveCalls--
		cs.ActiveChannels=cs.ActiveChannels-2
	default:
	}
}

func GetChannelStatus(event string, callStatus *CallStatus) {
	fmt.Println("GetChannelStatus function", event)
	for _, line := range strings.Split(event, "\r\n") {
		if strings.HasPrefix(line, "ChannelStateDesc: ") {
			state := strings.TrimSpace(strings.TrimPrefix(line, "ChannelStateDesc: "))
			callStatus.UpdateCallStatus(state)
		}
	}
}



答案1

得分: 1

我已经翻译好了,以下是代码的中文翻译:

// server.go

parts := strings.Split(line, ": ")
if len(parts) == 2 {
key := parts[0]
value := parts[1]

if key == "Event" {
    object.Event = value
}
if key == "ChannelState" {
    object.ChannelState = value
}
if key == "Linkedid" {
    object.Linkedid = value
}

}
data.HandleEvent(object, activeCalls)

// calls.go

package data

import (
"encoding/json"
"fmt"
)

type Data struct {
Event string json:"Event"
ChannelState string json:"ChannelState"
Linkedid string json:"Linkedid"
}

type ActiveCalls struct {
Count int json:"active_calls"
}

func HandleEvent(data Data, activeCalls *ActiveCalls) {
if data.Event == "Newstate" {
fmt.Println(data.ChannelState)
if data.ChannelState == "6" {
activeCalls.Count++
fmt.Println("Newstate count active calls", activeCalls.Count)
}
} else if data.Event == "Hangup" {
fmt.Println(data.ChannelState)
activeCalls.Count--
if activeCalls.Count < 0 {
activeCalls.Count = 0
}
fmt.Println("Newstate count active calls after hangup", activeCalls.Count)
}
}

func ActiveCallsToJSON(activeCalls *ActiveCalls) (string, error) {
jsonBytes, err := json.Marshal(activeCalls)
if err != nil {
return "", err
}
return string(jsonBytes), nil
}

英文:

I've figured it out, here is the code:
//server.go

parts := strings.Split(line, &quot;: &quot;)
	if len(parts) == 2 {
		key := parts[0]
		value := parts[1]

		if key == &quot;Event&quot; {
			object.Event = value
		}
		if key == &quot;ChannelState&quot; {
			object.ChannelState = value
		}
		if key == &quot;Linkedid&quot; {
			object.Linkedid = value
		}
	}
	data.HandleEvent(object, activeCalls)

calls.go

package data

import (
&quot;encoding/json&quot;
&quot;fmt&quot;
)

type Data struct {
Event        string `json:&quot;Event&quot;`
ChannelState string `json:&quot;ChannelState&quot;`
Linkedid     string `json:&quot;Linkedid&quot;`
}

type ActiveCalls struct {
Count int `json:&quot;active_calls&quot;`
}

func HandleEvent(data Data, activeCalls 
*ActiveCalls) {
if data.Event == &quot;Newstate&quot; {
	fmt.Println(data.ChannelState)
	if data.ChannelState == &quot;6&quot; {
		activeCalls.Count++
		fmt.Println(&quot;Newstate count active 
calls&quot;, activeCalls.Count)
	}
} else if data.Event == &quot;Hangup&quot; {
	fmt.Println(data.ChannelState)
	activeCalls.Count--
	if activeCalls.Count &lt; 0 {
		activeCalls.Count = 0
	}
	fmt.Println(&quot;Newstate count active calls after hangup&quot;, activeCalls.Count)
}
}

func ActiveCallsToJSON(activeCalls *ActiveCalls) (string, error) {
jsonBytes, err := json.Marshal(activeCalls)
if err != nil {
	return &quot;&quot;, err
}
return string(jsonBytes), nil

}

答案2

得分: 0

你应该发出动作类型为"COMMAND"的指令并读取结果。

指令可以是:
1)这个指令显示通道的总数
core show channels count

2)这个指令以人类可读的格式显示通道
core show channels

3)这个指令以机器/可解析的格式显示通道
core show channels concise

请注意,这可能不是非常可靠的方法。你需要自己计算或使用一些拨号计划阻止器(如函数GROUP/GROUP_COUNT)来获得可靠的结果。

你可以通过UserEvent拨号计划命令从你的拨号计划发送自定义事件。

是的,Asterisk是一个需要状态机知识(拨号计划)才能管理的PBX。至少不是可靠的。

英文:

You should issue action type "COMMAND" and read a result.

Commands can be

  1. this one shows total of channels

    core show channels count

  2. this one shows channels in human-readable format

    core show channels

  3. this one show in machine/parsable

    core show channels concise

Please note, that it may be not very reliable way. You have count yourself or use some dialplan blockers like function GROUP/GROUP_COUNT to make reliable results.

You can send custom event from your dialplan by UserEvent dialplan command.

Yes, asterisk is PBX which is not manageable without state machine knowledge(dialplan). At least not reliable.

huangapple
  • 本文由 发表于 2023年3月14日 18:37:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75732055.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定