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  }