+ // Forward output events from XDSServer to client through WS
+ // TODO use XDSServer events names definition
+ var fwdFuncID []uuid.UUID
+ evtOutList := []string{
+ xaapiv1.ExecOutEvent,
+ xaapiv1.ExecInferiorOutEvent,
+ }
+ for _, evName := range evtOutList {
+ evN := evName
+ fwdFunc := func(pData interface{}, evData interface{}) error {
+ sid := pData.(string)
+ // IO socket can be nil when disconnected
+ so := s.sessions.IOSocketGet(sid)
+ if so == nil {
+ s.Log.Infof("%s not emitted: WS closed (sid:%s)", evN, sid)
+ return nil
+ }
+
+ // Add sessionID to event Data
+ reflectme.SetField(evData, "sessionID", sid)
+
+ if s.LogLevelSilly {
+ s.Log.Debugf("EXEC EVENT OUT (%s) <<%v>>", evN, evData)
+ }
+
+ // Forward event to Client/Dashboard
+ (*so).Emit(evN, evData)
+ return nil
+ }
+ id, err := svr.EventOn(evN, sess.ID, fwdFunc)
+ if err != nil {
+ common.APIError(c, err.Error())
+ return
+ }
+ fwdFuncID = append(fwdFuncID, id)
+ }
+
+ // Handle Exit event separately to cleanup registered listener
+ var exitFuncID uuid.UUID
+ exitFunc := func(privD interface{}, evData interface{}) error {
+ evN := xaapiv1.ExecExitEvent
+
+ pData := privD.(map[string]string)
+ sid := pData["sessID"]
+ prjID := pData["prjID"]
+
+ // Add sessionID to event Data
+ reflectme.SetField(evData, "sessionID", sid)
+
+ // IO socket can be nil when disconnected
+ so := s.sessions.IOSocketGet(sid)
+ if so != nil {
+ (*so).Emit(evN, evData)
+ } else {
+ s.Log.Infof("%s not emitted: WS closed (sid:%s)", evN, sid)
+ }
+
+ prj := s.projects.Get(prjID)
+ if prj != nil {
+ evD := evData.(map[string]interface{})
+ cmdIDData, cmdIDExist := evD["cmdID"]
+ svr := (*prj).GetServer()
+ if svr != nil && cmdIDExist {
+ svr.CommandDelete(cmdIDData.(string))
+ } else {
+ s.Log.Infof("%s: cannot retrieve server for sid=%s, prjID=%s, evD=%v", evN, sid, prjID, evD)
+ }
+ } else {
+ s.Log.Infof("%s: cannot retrieve project for sid=%s, prjID=%s", evN, sid, prjID)
+ }
+
+ // cleanup listener
+ for i, evName := range evtOutList {
+ svr.EventOff(evName, fwdFuncID[i])
+ }
+ svr.EventOff(evN, exitFuncID)
+
+ return nil
+ }
+
+ prjCfg := (*prj).GetProject()
+ privData := map[string]string{"sessID": sess.ID, "prjID": prjCfg.ID}
+ exitFuncID, err = svr.EventOn(xaapiv1.ExecExitEvent, privData, exitFunc)