package ami import ( "fmt" socketio "pms-api-go/internal/app/socket_io" "pms-api-go/pkg/lfshook" "sync" "github.com/mitchellh/mapstructure" ) var bridgeMap sync.Map const bridgeEventName = "CustomBridgeEvent" type BridgeEvent struct { Event string `json:"event"` // Timestamp string `json:"timestamp"` BridgeUniqueid string `json:"-"` Channel string `json:"channel"` ChannelState string `json:"channelState"` ChannelStateDesc string `json:"channelStateDesc"` CallerIDNum string `json:"callerIDNumber"` CallerIDName string `json:"callerIDName"` CallerConnectedLineNum string `json:"callerConnectedLineNumber"` CallerConnectedLineName string `json:"callerConnectedLineName"` BridgeType string `json:"bridgeType"` BridgeNumChannels string `json:"bridgeNumberChannels"` Uniqueid string `json:"uniqueid"` } func (event BridgeEvent) String() string { return fmt.Sprintf("channel: %s, uniqueid: %s\n", event.Channel, event.Uniqueid) } func handleAMIBridge(event map[string]string) { if event["BridgeType"] != "basic" { return } if event["CallerIDName"] == "conference" { return } switch event["Event"] { case "BridgeCreate": bridgeMap.Store(event["BridgeUniqueid"], []*BridgeEvent{}) case "BridgeEnter": status := &BridgeEvent{} mapstructure.Decode(event, status) if events, ok := bridgeMap.Load(status.BridgeUniqueid); ok { bridgeMap.Store(status.BridgeUniqueid, append(events.([]*BridgeEvent), status)) } else { lfshook.NewLogger().Warnf("BridgeEnter add failure id: %s on load", status.BridgeUniqueid) } socketio.SocketIOServer.BroadcastToNamespace("", bridgeEventName, GetBridgeMapValue()) case "BridgeLeave": status := &BridgeEvent{} mapstructure.Decode(event, status) if events, ok := bridgeMap.Load(status.BridgeUniqueid); ok { events := events.([]*BridgeEvent) for index, event := range events { if event.Channel == status.Channel { if index == len(events)-1 { bridgeMap.Store(status.BridgeUniqueid, events[:index]) } else { bridgeMap.Store(status.BridgeUniqueid, append(events[:index], events[index+1])) } break } } } else { lfshook.NewLogger().Warnf("BridgeLeave remove failure id: %s on load", status.BridgeUniqueid) } socketio.SocketIOServer.BroadcastToNamespace("", bridgeEventName, GetBridgeMapValue()) case "BridgeDestroy": bridgeMap.Delete(event["BridgeUniqueid"]) socketio.SocketIOServer.BroadcastToNamespace("", bridgeEventName, GetBridgeMapValue()) } } func GetBridgeMapValue() (result map[string][]*BridgeEvent) { result = make(map[string][]*BridgeEvent) bridgeMap.Range(func(key, value interface{}) bool { events := value.([]*BridgeEvent) result[key.(string)] = events return true }) return } // ClearBridge Asterisk 重启,内部通话清空, AMI 重连成功也需求清空 Bridge func ClearBridge() { bridgeMap.Range(func(key, value interface{}) bool { bridgeMap.Delete(key) return true }) }