golang Asterisk PBX AMI v2 协议库插件goami2的使用

golang Asterisk PBX AMI v2 协议库插件goami2的使用

简介

goami2是一个简单的Asterisk Manager Interface (AMI)库,它提供了与Asterisk PBX系统交互的接口。该库使用给定的net.Conn(TCP或TLS)连接,登录后开始从连接读取AMI消息并将其解析为*Message对象。同时提供了简单的接口来发送消息到AMI。

使用示例

下面是一个完整的goami2使用示例代码:

import (
	"errors"
	"fmt"
	"log"
	"net"

	"github.com/staskobzar/goami2"
)

func main() {
	// 建立TCP连接
	conn, err := net.Dial("tcp", "asterisk.host:5038")
	if err != nil {
		log.Fatalln(err)
	}

	// 登录并创建客户端
	client, err := goami2.NewClient(conn, "admin", "pa55w0rd")
	if err != nil {
		log.Fatalln(err)
	}

	log.Println("客户端已连接并登录")

	// 创建AMI Action消息并发送到asterisk.host
	msg := goami2.NewAction("CoreStatus")
	msg.AddActionID()
	client.Send(msg.Byte())

	defer client.Close() // 关闭连接和所有通道
	for {
		select {
		case msg := <-client.AllMessages():
			log.Printf("收到消息: %s\n", msg.JSON())
		case err := <-client.Err():
			// 网络关闭时终止
			if errors.Is(err, goami2.ErrEOF) {
				log.Fatalf("连接错误: %s", err)
			}
			log.Printf("警告: AMI客户端错误: %s", err)
		}
	}
}

代码说明

  1. 连接建立:

    • 使用net.Dial建立到Asterisk服务器的TCP连接(默认端口5038)
  2. 客户端创建:

    • 使用goami2.NewClient创建AMI客户端,需要提供连接对象、用户名和密码
  3. 消息发送:

    • 使用NewAction创建新的AMI动作
    • AddActionID为消息添加唯一的ActionID
    • Send方法发送消息到Asterisk服务器
  4. 消息接收:

    • AllMessages通道接收所有来自Asterisk的消息
    • Err通道接收错误信息
    • 使用JSON方法可以将消息转换为JSON格式
  5. 资源清理:

    • defer client.Close()确保程序退出时正确关闭连接

功能特点

  1. 支持AMI v2协议
  2. 使用re2c创建高性能协议解析器
  3. 提供简单的消息发送和接收接口
  4. 支持错误处理
  5. 可以将消息转换为JSON格式

这个库非常适合需要与Asterisk PBX系统集成的Golang应用程序,可以方便地实现监控、控制和管理功能。


更多关于golang Asterisk PBX AMI v2 协议库插件goami2的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang Asterisk PBX AMI v2 协议库插件goami2的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


GoAMI2 - Golang Asterisk PBX AMI v2 协议库使用指南

GoAMI2 是一个用于与 Asterisk PBX 管理接口(AMI) v2 协议交互的 Golang 库。下面我将详细介绍如何使用这个库。

安装

首先安装 goami2 库:

go get github.com/ivahaev/goami2

基本连接

package main

import (
	"log"
	"github.com/ivahaev/goami2"
)

func main() {
	// 创建AMI客户端
	client := goami2.NewClient("127.0.0.1:5038", "admin", "password")
	
	// 设置事件处理器
	client.On("connect", func(message *goami2.Message) {
		log.Println("Connected to AMI")
	})
	
	// 连接AMI
	err := client.Connect()
	if err != nil {
		log.Fatal("Connection error:", err)
	}
	defer client.Close()
	
	// 保持连接
	select {}
}

发送命令

// 发送Ping命令
msg := goami2.NewMessage("Ping")
response, err := client.Send(msg)
if err != nil {
    log.Println("Error sending Ping:", err)
} else {
    log.Println("Ping response:", response)
}

// 获取SIP对等端状态
peersMsg := goami2.NewMessage("SIPpeers")
peersResponse, err := client.Send(peersMsg)
if err != nil {
    log.Println("Error getting SIP peers:", err)
} else {
    log.Println("SIP peers:", peersResponse)
}

事件监听

// 监听所有事件
client.On("event", func(msg *goami2.Message) {
    event := msg.Get("Event")
    log.Printf("Received event: %s", event)
})

// 监听特定事件
client.On("Newchannel", func(msg *goami2.Message) {
    channel := msg.Get("Channel")
    log.Printf("New channel created: %s", channel)
})

client.On("Hangup", func(msg *goami2.Message) {
    channel := msg.Get("Channel")
    cause := msg.Get("Cause")
    log.Printf("Channel %s hung up. Cause: %s", channel, cause)
})

发起呼叫

func originateCall(client *goami2.Client, from, to string) {
    msg := goami2.NewMessage("Originate")
    msg.Set("Channel", "SIP/"+from)
    msg.Set("Exten", to)
    msg.Set("Context", "from-internal")
    msg.Set("Priority", "1")
    msg.Set("CallerID", "Call from "+from)
    msg.Set("Timeout", "30000")
    msg.Set("Async", "true")

    response, err := client.Send(msg)
    if err != nil {
        log.Println("Error originating call:", err)
    } else {
        log.Println("Originate response:", response)
    }
}

完整示例

package main

import (
	"log"
	"time"
	"github.com/ivahaev/goami2"
)

func main() {
	client := goami2.NewClient("127.0.0.1:5038", "admin", "password")
	
	// 设置事件处理器
	client.On("connect", func(msg *goami2.Message) {
		log.Println("Connected to AMI")
		
		// 连接后发送Ping
		pingMsg := goami2.NewMessage("Ping")
		response, err := client.Send(pingMsg)
		if err != nil {
			log.Println("Ping error:", err)
		} else {
			log.Println("Ping response:", response)
		}
	})
	
	client.On("event", func(msg *goami2.Message) {
		event := msg.Get("Event")
		if event != "" {
			log.Printf("Event: %s", event)
		}
	})
	
	client.On("Newchannel", func(msg *goami2.Message) {
		log.Printf("New channel: %s", msg.Get("Channel"))
	})
	
	// 连接AMI
	err := client.Connect()
	if err != nil {
		log.Fatal("Connection error:", err)
	}
	defer client.Close()
	
	// 5秒后发起测试呼叫
	time.AfterFunc(5*time.Second, func() {
		originateCall(client, "1001", "1002")
	})
	
	// 保持程序运行
	select {}
}

func originateCall(client *goami2.Client, from, to string) {
	msg := goami2.NewMessage("Originate")
	msg.Set("Channel", "SIP/"+from)
	msg.Set("Exten", to)
	msg.Set("Context", "from-internal")
	msg.Set("Priority", "1")
	msg.Set("CallerID", "Call from "+from)
	msg.Set("Timeout", "30000")
	msg.Set("Async", "true")

	response, err := client.Send(msg)
	if err != nil {
		log.Println("Error originating call:", err)
	} else {
		log.Println("Originate response:", response)
	}
}

高级用法

自定义超时

client := goami2.NewClient("127.0.0.1:5038", "admin", "password")
client.Timeout = 10 * time.Second // 设置10秒超时

处理错误

client.On("error", func(err error) {
    log.Println("AMI error:", err)
    // 可以在这里实现重连逻辑
})

重连机制

func connectWithRetry(client *goami2.Client, maxRetries int) {
    var retries int
    for {
        err := client.Connect()
        if err == nil {
            return
        }
        
        retries++
        if retries >= maxRetries {
            log.Fatal("Max retries reached")
        }
        
        log.Printf("Connection failed, retrying in 5 seconds (attempt %d/%d)", retries, maxRetries)
        time.Sleep(5 * time.Second)
    }
}

GoAMI2 提供了简洁的 API 来与 Asterisk AMI 接口交互,支持命令发送和事件监听。通过合理使用这个库,可以构建强大的 Asterisk 管理工具和集成应用。

回到顶部