package service import ( "go_dreamfactory/cmd/v2/lib/common" "go_dreamfactory/cmd/v2/model" "go_dreamfactory/cmd/v2/service/observer" "go_dreamfactory/comm" "go_dreamfactory/pb" "io/ioutil" "net/http" "strings" "time" "github.com/gorilla/websocket" "github.com/sirupsen/logrus" "google.golang.org/protobuf/proto" ) var ( conn *ConnServiceImpl ) type ConnService interface { WsConnect(wsUrl string) error HttpConnect(url string) ([]byte, error) SendMsg(msg *pb.UserMessage, rsp proto.Message) (err error) ReceiveMsg() (errdata *pb.ErrorData, msg *pb.UserMessage) ListenerPush() Close() } type ConnServiceImpl struct { ws *websocket.Conn obs observer.Observer } func NewConnService(obs observer.Observer) ConnService { conn = &ConnServiceImpl{obs: obs} return conn } func GetConnService() *ConnServiceImpl { return conn } // connect ... func (c *ConnServiceImpl) WsConnect(wsUrl string) error { dialer := &websocket.Dialer{ HandshakeTimeout: 5 * time.Second, } ws, _, err := dialer.Dial(wsUrl, nil) if err != nil { logrus.Errorf("websocket conn err:%v", err) return err } c.ws = ws return nil } func (c *ConnServiceImpl) HttpConnect(url string) ([]byte, error) { res, err := http.Get(url) if err != nil { return nil, err } defer res.Body.Close() return ioutil.ReadAll(res.Body) } // listener push func (c *ConnServiceImpl) ListenerPush() { defer func() { if err := recover(); err != nil { logrus.Errorf("listenerPush err: %v", err) } }() go func() { for { // time.Sleep(time.Millisecond * 200) msg := &pb.UserMessage{} _, data, err := c.ws.ReadMessage() if err != nil { logrus.Errorf("readMessage err:%v", err) return } if err = proto.Unmarshal(data, msg); err != nil { return } // logrus.WithFields( // logrus.Fields{"MainType": msg.MainType, "SubType": msg.SubType}, // ).Debug(msg.Data.TypeUrl) methodStr := msg.Data.TypeUrl methodName := common.SubStr(methodStr, 20, len(methodStr)) p := &model.PushModel{ MethodName: methodName, DataTime: time.Now().Format(time.RFC3339), Msg: msg, } // logrus.WithFields( // logrus.Fields{"MainType": msg.MainType, "SubType": msg.SubType}, // ).Debug(methodName) renderRespPanel := func(p *model.PushModel) { c.obs.Notify(observer.EVENT_REQ_RSP, p.Msg) } if strings.HasSuffix(methodName, "Push") { c.obs.Notify(observer.EVENT_APP_MONI, p) c.obs.Notify(observer.EVENT_APP_MONI_EX, msg) c.obs.Notify(observer.EVENT_USER_CHANGE, p) if methodName == "NotifyErrorNotifyPush" { renderRespPanel(p) } } else { //render appTestcase respPanel renderRespPanel(p) } } }() } // SendMsg .... func (c *ConnServiceImpl) SendMsg(msg *pb.UserMessage, rsp proto.Message) (err error) { defer func() { if err := recover(); err != nil { logrus.Errorf("sendMsg %v", err) } }() // msg.Sec = r.BuildSecStr() if comm.ProtoMarshal(rsp, msg) { if data, err := proto.Marshal(msg); err != nil { return err } else { return c.ws.WriteMessage(websocket.BinaryMessage, data) } } return } // ReceiveMsg .... func (c *ConnServiceImpl) ReceiveMsg() (errdata *pb.ErrorData, msg *pb.UserMessage) { msg = &pb.UserMessage{} _, data, err := c.ws.ReadMessage() if err != nil { logrus.Errorf("readMessage err:%v", err) return } if err = proto.Unmarshal(data, msg); err != nil { return } if errdata = c.handleNotify(msg); errdata != nil { return } return } // err notify func (c *ConnServiceImpl) handleNotify(msg *pb.UserMessage) (errdata *pb.ErrorData) { if msg.MainType == "notify" && msg.SubType == "errornotify" { rsp := &pb.NotifyErrorNotifyPush{} if !comm.ProtoUnmarshal(msg, rsp) { errdata = &pb.ErrorData{ Code: pb.ErrorCode_PbError, } return } errdata = &pb.ErrorData{ Code: rsp.Code, } return } return } func (c *ConnServiceImpl) Close() { if err := c.ws.Close(); err != nil { logrus.Errorf("close ws conn err: %v", err) } }