github.com/CyCoreSystems/ari@v4.8.4+incompatible/_examples/stasisStart/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "net/http" 6 "sync" 7 8 "github.com/inconshreveable/log15" 9 10 "github.com/CyCoreSystems/ari" 11 "github.com/CyCoreSystems/ari/client/native" 12 ) 13 14 var log = log15.New() 15 16 func main() { 17 ctx, cancel := context.WithCancel(context.Background()) 18 defer cancel() 19 20 // connect 21 native.Logger = log 22 23 log.Info("Connecting to ARI") 24 cl, err := native.Connect(&native.Options{ 25 Application: "test", 26 Username: "admin", 27 Password: "admin", 28 URL: "http://localhost:8088/ari", 29 WebsocketURL: "ws://localhost:8088/ari/events", 30 }) 31 if err != nil { 32 log.Error("Failed to build ARI client", "error", err) 33 return 34 } 35 36 // setup app 37 38 log.Info("Starting listener app") 39 40 go listenApp(ctx, cl, channelHandler) 41 42 // start call start listener 43 44 log.Info("Starting HTTP Handler") 45 46 http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 47 // make call 48 log.Info("Make sample call") 49 h, err := createCall(cl) 50 if err != nil { 51 log.Error("Failed to create call", "error", err) 52 w.WriteHeader(http.StatusBadGateway) 53 w.Write([]byte("Failed to create call: " + err.Error())) 54 return 55 } 56 57 w.WriteHeader(http.StatusOK) 58 w.Write([]byte(h.ID())) 59 })) 60 61 log.Info("Listening for requests on port 9990") 62 http.ListenAndServe(":9990", nil) 63 64 return 65 } 66 67 func listenApp(ctx context.Context, cl ari.Client, handler func(cl ari.Client, h *ari.ChannelHandle)) { 68 sub := cl.Bus().Subscribe(nil, "StasisStart") 69 end := cl.Bus().Subscribe(nil, "StasisEnd") 70 71 for { 72 select { 73 case e := <-sub.Events(): 74 v := e.(*ari.StasisStart) 75 log.Info("Got stasis start", "channel", v.Channel.ID) 76 go handler(cl, cl.Channel().Get(v.Key(ari.ChannelKey, v.Channel.ID))) 77 case <-end.Events(): 78 log.Info("Got stasis end") 79 case <-ctx.Done(): 80 return 81 } 82 } 83 84 } 85 86 func createCall(cl ari.Client) (h *ari.ChannelHandle, err error) { 87 h, err = cl.Channel().Create(nil, ari.ChannelCreateRequest{ 88 Endpoint: "Local/1000", 89 App: "example", 90 }) 91 92 return 93 } 94 95 func connect(ctx context.Context) (cl ari.Client, err error) { 96 97 log.Info("Connecting") 98 99 cl, err = native.Connect(&native.Options{}) 100 return 101 } 102 103 func channelHandler(cl ari.Client, h *ari.ChannelHandle) { 104 log.Info("Running channel handler") 105 106 stateChange := h.Subscribe(ari.Events.ChannelStateChange) 107 defer stateChange.Cancel() 108 109 data, err := h.Data() 110 if err != nil { 111 log.Error("Error getting data", "error", err) 112 return 113 } 114 log.Info("Channel State", "state", data.State) 115 116 var wg sync.WaitGroup 117 118 wg.Add(1) 119 go func() { 120 log.Info("Waiting for channel events") 121 122 defer wg.Done() 123 124 for { 125 select { 126 case <-stateChange.Events(): 127 log.Info("Got state change request") 128 129 data, err = h.Data() 130 if err != nil { 131 log.Error("Error getting data", "error", err) 132 continue 133 } 134 log.Info("New Channel State", "state", data.State) 135 136 if data.State == "Up" { 137 stateChange.Cancel() // stop subscription to state change events 138 return 139 } 140 } 141 } 142 143 }() 144 145 h.Answer() 146 147 wg.Wait() 148 149 h.Hangup() 150 }