bridge.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package ami
  2. import (
  3. "fmt"
  4. "pbx-api-gin/pkg/lfshook"
  5. "sync"
  6. "github.com/mitchellh/mapstructure"
  7. )
  8. var bridgeMap sync.Map
  9. const bridgeEventName = "CustomBridgeEvent"
  10. type BridgeEvent struct {
  11. Event string `json:"event"`
  12. // Timestamp string `json:"timestamp"`
  13. BridgeUniqueid string `json:"-"`
  14. Channel string `json:"channel"`
  15. ChannelState string `json:"channelState"`
  16. ChannelStateDesc string `json:"channelStateDesc"`
  17. CallerIDNum string `json:"callerIDNumber"`
  18. CallerIDName string `json:"callerIDName"`
  19. CallerConnectedLineNum string `json:"callerConnectedLineNumber"`
  20. CallerConnectedLineName string `json:"callerConnectedLineName"`
  21. BridgeType string `json:"bridgeType"`
  22. BridgeNumChannels string `json:"bridgeNumberChannels"`
  23. Uniqueid string `json:"uniqueid"`
  24. }
  25. func (event BridgeEvent) String() string {
  26. return fmt.Sprintf("channel: %s, uniqueid: %s\n", event.Channel, event.Uniqueid)
  27. }
  28. func handleAMIBridge(event map[string]string) {
  29. if event["BridgeType"] != "basic" {
  30. return
  31. }
  32. if event["CallerIDName"] == "conference" {
  33. return
  34. }
  35. switch event["Event"] {
  36. case "BridgeCreate":
  37. bridgeMap.Store(event["BridgeUniqueid"], []*BridgeEvent{})
  38. case "BridgeEnter":
  39. status := &BridgeEvent{}
  40. mapstructure.Decode(event, status)
  41. if events, ok := bridgeMap.Load(status.BridgeUniqueid); ok {
  42. bridgeMap.Store(status.BridgeUniqueid, append(events.([]*BridgeEvent), status))
  43. } else {
  44. lfshook.NewLogger().Warnf("BridgeEnter add failure id: %s on load", status.BridgeUniqueid)
  45. }
  46. //socketio.SocketIOServer.BroadcastToNamespace("", bridgeEventName, GetBridgeMapValue())
  47. case "BridgeLeave":
  48. status := &BridgeEvent{}
  49. mapstructure.Decode(event, status)
  50. if events, ok := bridgeMap.Load(status.BridgeUniqueid); ok {
  51. events := events.([]*BridgeEvent)
  52. for index, event := range events {
  53. if event.Channel == status.Channel {
  54. if index == len(events)-1 {
  55. bridgeMap.Store(status.BridgeUniqueid, events[:index])
  56. } else {
  57. bridgeMap.Store(status.BridgeUniqueid, append(events[:index], events[index+1]))
  58. }
  59. break
  60. }
  61. }
  62. } else {
  63. lfshook.NewLogger().Warnf("BridgeLeave remove failure id: %s on load", status.BridgeUniqueid)
  64. }
  65. //socketio.SocketIOServer.BroadcastToNamespace("", bridgeEventName, GetBridgeMapValue())
  66. case "BridgeDestroy":
  67. bridgeMap.Delete(event["BridgeUniqueid"])
  68. //socketio.SocketIOServer.BroadcastToNamespace("", bridgeEventName, GetBridgeMapValue())
  69. }
  70. }
  71. func GetBridgeMapValue() (result map[string][]*BridgeEvent) {
  72. result = make(map[string][]*BridgeEvent)
  73. bridgeMap.Range(func(key, value interface{}) bool {
  74. events := value.([]*BridgeEvent)
  75. result[key.(string)] = events
  76. return true
  77. })
  78. return
  79. }
  80. // ClearBridge Asterisk 重启,内部通话清空, AMI 重连成功也需求清空 Bridge
  81. func ClearBridge() {
  82. bridgeMap.Range(func(key, value interface{}) bool {
  83. bridgeMap.Delete(key)
  84. return true
  85. })
  86. }