func (chn *Channel) handleUnregisterRes(clientID uint32, data []byte) { request, _, err := chn.getReqParam(clientID, data) if err != nil { mylog.GetErrorLogger().Println("handleUnregisterRes", err) chn.sendProto(clientID, base.UNREGISTER_RESOURCE, "", base.PROTOERR400, request.Ns) return } param := request.Param.(map[string]interface{}) resourceID := param["resourceid"].(string) func() { chn.resMutex.Lock() defer chn.resMutex.Unlock() resourcer, ok := chn.registerRes[resourceID] if ok { mylog.GetErrorLogger().Fatalln("Release Resource ", resourceID) resourcer.Unregister() ReleaseResourcer(resourcer) delete(chn.registerRes, resourceID) } }() chn.sendProto(clientID, base.UNREGISTER_RESOURCE, "", base.OK, request.Ns) }
func (p *Proto) ReadBinaryProto(connSocket net.Conn) error { tmpBaseHdSlice := make([]byte, BaseHeaderLenC) { n, e := io.ReadFull(connSocket, tmpBaseHdSlice) if e != nil { mylog.GetErrorLogger().Println("311", e) return e } if n != BaseHeaderLenC { return DTerror{PROTOERR400} } (&p.RD.BaseHD).Decode(tmpBaseHdSlice) if p.RD.BaseHD.CommandId == HEART_CMD || p.RD.BaseHD.HeaderLen == 0 { return nil } } if p.RD.BaseHD.HeaderLen != HeaderLenC { mylog.GetErrorLogger().Println("Recv Msg Error 1", p.RD.BaseHD.HeaderLen) return DTerror{PROTOERR400} } tmpHdSlice := make([]byte, HeaderLenC) { n, e := io.ReadFull(connSocket, tmpHdSlice) if e != nil { return e } if n != HeaderLenC { return DTerror{PROTOERR400} } (&p.RD.HD).Decode(tmpHdSlice) if p.RD.HD.BodyLen <= 4 || p.RD.HD.BodyLen > M1 { mylog.GetErrorLogger().Println("Recv Msg Error 2", p.RD.HD.BodyLen) return nil } } p.BD = new(Body) p.BD.Data = make([]byte, p.RD.HD.BodyLen) { n, e := io.ReadFull(connSocket, p.BD.Data) if e != nil { return e } if n != int(p.RD.HD.BodyLen) { return DTerror{PROTOERR400} } //fmt.Println("Recv Msg Error", body.DataLen) } return nil }
func (chn *Channel) getReqParam(clientID uint32, data []byte) (*base.RequestJson, *base.TokenJson, error) { var request base.RequestJson err := json.Unmarshal(data, &request) if err != nil { mylog.GetErrorLogger().Println("getReqParam", err, string(data)) return nil, nil, base.DTerror{base.PROTOERR400} } //token权限验证 var rightJson base.TokenJson mylog.GetErrorLogger().Println("token ", string(data)) if len(request.Token) <= 0 { return &request, nil, nil } rightErr := base.UnmarshalToken(request.Token, &rightJson) if rightErr != nil { mylog.GetErrorLogger().Println("getReqParam", err) return nil, nil, base.DTerror{base.PROTOERR400} } return &request, &rightJson, nil }
// 注销资源 func (r *Resourcer) Unregister() { defer func() { if re := recover(); re != nil { mylog.GetErrorLogger().Println(r.GetID(), "unregister Resource panic", re) } }() atomic.CompareAndSwapUint32(&r.valid, 1, 0) r.mutex.Lock() defer r.mutex.Unlock() mylog.GetErrorLogger().Println("Unregister Close") close(r.ClientOpenChn) { for _, chn := range r.ClientDataChn { chn.ClientInf.Notify(r.GetID(), chn.ClientID, LEAVE_EVENT) } } r.Result = "" r.Error = "" }
func runTcp() error { lnSocket, err := net.Listen("tcp", "localhost:9999") if err != nil { mylog.GetErrorLogger().Println(err) return err } defer lnSocket.Close() for { connSocket, err := lnSocket.Accept() if err != nil { mylog.GetErrorLogger().Println(err) return err } fmt.Println("Recv Connect", connSocket.LocalAddr().String()) //fileHandler, _ := os.OpenFile("my1.h264", os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0777) proxy := BindFfmpegForProxy(connSocket) if proxy != nil { proxy.run() } } return nil }
func (chn *Channel) handleReqCloseRes(clientID uint32, data []byte) { mylog.GetErrorLogger().Println("handleReqCloseRes", string(data[4:])) defer func() { if r := recover(); r != nil { chn.sendProto(clientID, base.CLOSE_RESOURCE_CMD, "", base.PROTOERR400, "huamail.defualt") chn.handleError(base.DTerror{"handleReqCloseRes Panic"}) } }() var responseResult, responseErr string = "", base.NOFOUNF404 request, _, err := chn.getReqParam(clientID, data[4:]) if err != nil { chn.sendProto(clientID, base.CLOSE_RESOURCE_CMD, responseResult, err.Error(), "huamail.defualt") return } func() { chn.resMutex.Lock() defer chn.resMutex.Unlock() resourcer, ok := chn.openRes[clientID] if ok { mylog.GetErrorLogger().Println("Chn Close Resource ID ", resourcer.GetID()) clientDataID := new(ResourceClient) clientDataID.ClientInf = chn clientDataID.ClientID = clientID responseResult, responseErr = resourcer.Close(clientDataID, "", false) ReleaseResourcer(resourcer) delete(chn.openRes, clientID) } }() proto := base.GetProto() proto.RD.BaseHD.CommandId = 0x80 | base.CLOSE_RESOURCE_CMD proto.RD.HD.ClientIdent = clientID responseJson := base.ResponseJson{request.Ns, request.Method, responseResult, responseErr} b, err := json.Marshal(responseJson) if err != nil { mylog.GetErrorLogger().Println("handleCloseResource : ", err) } proto.EncodeBody(b) chn.Send(proto) stat.GetLocalStatistInst().CloseRes() }
func (pu *PUDevice) readTask() { defer func() { if r := recover(); r != nil { mylog.GetErrorLogger().Println("readTask panic") return } }() for { proto := new(base.Proto) err := proto.ReadBinaryProto(pu.connSocket) if err != nil { pu.handleError(err) break } cmdID := proto.RD.BaseHD.CommandId & 0x7f if cmdID == base.HEART_CMD { mylog.GetErrorLogger().Println("Recv And Send Heart", proto.RD.BaseHD.CommandId) heartProto := new(base.Proto) heartProto.RD.BaseHD.CommandId = 0x80 | cmdID pu.rwChan <- heartProto } else { mylog.GetErrorLogger().Println(string(proto.BD.Data[4:])) if cmdID == base.OPEN_RESOURCE_CMD { go pu.openSource(proto.RD.HD.ClientIdent) } else if cmdID == base.CLOSE_RESOURCE_CMD { go pu.closeSource(proto.RD.HD.ClientIdent) } else if cmdID == base.REGISTER_RESOURCE { var reponseJson base.ResponseJson resErr := json.Unmarshal(proto.BD.Data[4:], &reponseJson) if resErr != nil { pu.handleError(resErr) return } if reponseJson.Error != base.OK { pu.handleError(base.DTerror{"Resoure Fail"}) fmt.Println(reponseJson.Error) return } stat.GetLocalStatistInst().RegisterRes() } } } }
func (chn *Channel) handleOtherCMD(proto *base.Proto) { cmdID := proto.RD.BaseHD.CommandId mylog.GetErrorLogger().Println("handleOtherCMD", cmdID) error := base.NOSUPPORT501 responseJson := base.ResponseJson{"", "", "", error} b, err := json.Marshal(responseJson) if err != nil { mylog.GetErrorLogger().Println("handleOtherCMD : ", err) } proto.EncodeBody(b) chn.Send(proto) }
// 内部访问接口 // 错误处理 func (chn *Channel) handleError(err error) { defer func() { if r := recover(); r != nil { mylog.GetErrorLogger().Println("Channel handleError Panic") } }() if err != nil { mylog.GetErrorLogger().Println("handleError", err.Error()) } if atomic.CompareAndSwapUint32(&chn.valid, 0, 0) { return } atomic.CompareAndSwapUint32(&chn.valid, 1, 0) stat.GetLocalStatistInst().Off() func() { chn.resMutex.Lock() defer chn.resMutex.Unlock() for _, r := range chn.openRes { stat.GetLocalStatistInst().CloseRes() mylog.GetErrorLogger().Println(" release chn res ", r.GetID()) clientDataID := new(ResourceClient) clientDataID.ClientInf = chn r.Close(clientDataID, "", true) ReleaseResourcer(r) } for _, v := range chn.registerRes { v.Unregister() ReleaseResourcer(v) } }() func() { fmt.Println("Chn Close") chn.chnMutex.Lock() defer chn.chnMutex.Unlock() chn.connSocket.Close() close(chn.rwChn) close(chn.notifyChn) }() }
func main() { // 减少内存分配 parseArg() devCount := oneEnvParam.ResourceCount stat.GetLocalStatistInst().Init("pu_llog", "logic.dat", int32(devCount)) go stat.GetLocalStatistInst().Start() mylog.GetErrorLogger().Init("pu_elog", "error.log") go stat.StartMonitorTask("pu_mlog", "monitor.dat") for i := oneEnvParam.BeginID; i <= devCount; i++ { sn := new(bytes.Buffer) fmt.Fprintf(sn, "%v", strconv.Itoa(int(i))) var pu *PUDevice = new(PUDevice) pu.run(sn.String()) } for { time.Sleep(10 * time.Minute) } }
func (chn *Channel) handleEventNotify(event notifyEvent) { func() { chn.resMutex.Lock() defer chn.resMutex.Unlock() resourcer, ok := chn.openRes[event.clientID] if ok { ReleaseResourcer(resourcer) delete(chn.openRes, event.clientID) } }() proto := base.GetProto() proto.RD.BaseHD.CommandId = base.LEAVE_NOTIFY proto.RD.HD.ClientIdent = event.clientID proto.RD.HD.ContextType = base.CONTEXT_JSON proto.RD.HD.TransferType = base.TRANSFER_RAW leaveNotify := base.LeaveNotifyParamJson{event.resourceID} request := base.RequestJson{"", "ns", "notify", leaveNotify} requestJson, err := json.Marshal(request) if err != nil { mylog.GetErrorLogger().Println("Resource Unregister Json ", err) } proto.EncodeBody(requestJson) chn.Send(proto) }
func (chn *Channel) sendProto(cID uint32, cmd uint8, result string, err string, ns string) { var method string if cmd == base.OPEN_RESOURCE_CMD { method = "open" } else if cmd == base.CLOSE_RESOURCE_CMD { method = "close" } else if cmd == base.REGISTER_RESOURCE { method = "register" } proto := base.GetProto() proto.RD.BaseHD.CommandId = 0x80 | cmd proto.RD.HD.ClientIdent = cID proto.RD.HD.ContextType = base.CONTEXT_JSON proto.RD.HD.TransferType = base.TRANSFER_RAW responseJson := base.ResponseJson{ns, method, result, err} b, jsonE := json.Marshal(responseJson) if jsonE != nil { mylog.GetErrorLogger().Println("handleOpenResource : ", jsonE) } proto.EncodeBody(b) go chn.Send(proto) }
// 取消资源 func (r *Resourcer) unattent(chn *ResourceClient, all bool) int { resultChn := make([]*ResourceClient, 0) for _, v := range r.ClientDataChn { if all { if v.ClientInf != chn.ClientInf { resultChn = append(resultChn, v) } } else if (v.ClientID != chn.ClientID) || (v.ClientInf != chn.ClientInf) { resultChn = append(resultChn, v) } else { mylog.GetErrorLogger().Println("unattent Resource error", r.GetID()) } } r.ClientDataChn = resultChn mylog.GetErrorLogger().Println(r.GetID(), " unattent Resource Len ", len(r.ClientDataChn)) return len(r.ClientDataChn) }
// 心跳处理,主动发起心跳 func (chn *Channel) timerSendHeartTask() { mylog.GetErrorLogger().Println(" Begin Chn Heart Task") defer func() { if r := recover(); r != nil { chn.handleError(base.DTerror{"Notify Panic"}) } }() proto := base.GetProto() proto.RD.BaseHD.CommandId = base.HEART_CMD var failCount int = 0 for { if atomic.CompareAndSwapUint32(&chn.valid, 0, 0) { break } if !chn.Send(proto) { chn.handleError(base.DTerror{"Send Error"}) break } select { case <-chn.heartChn: failCount = 0 case <-time.After(2 * time.Second): failCount++ } if failCount >= 5 { chn.handleError(base.DTerror{"Heart Send Fail"}) break } time.Sleep(10 * time.Second) } mylog.GetErrorLogger().Println(" End Chn Heart Task") }
func runTcp() error { lnSocket, err := net.Listen("tcp", oneEnvParam.url) if err != nil { mylog.GetErrorLogger().Println(err) return err } defer lnSocket.Close() for { connSocket, err := lnSocket.Accept() if err != nil { mylog.GetErrorLogger().Println(err) return err } mylog.GetErrorLogger().Println("Remote Connect Addr : ", connSocket.RemoteAddr().String()) go handleConnect(connSocket) } return nil }
func (pu *PUDevice) handleError(err error) { mylog.GetErrorLogger().Println(err) if atomic.CompareAndSwapUint32(&pu.Valid, 0, 0) { return } atomic.CompareAndSwapUint32(&pu.Valid, 1, 0) pu.connSocket.Close() stat.GetLocalStatistInst().Off() if atomic.CompareAndSwapUint32(&pu.SendFlag, 1, 1) { stat.GetLocalStatistInst().CloseRes() } close(pu.rwChan) go pu.ReRun(pu.SN) }
// 外部访问接口,由资源通知资源订阅者相关事件 // 对外部访问接口枷锁保护,以后的版本采用消息机制,去除锁 func (chn *Channel) Notify(resourceID string, clientID uint32, event int) bool { defer func() { if r := recover(); r != nil { err := base.DTerror{"Notify Panic"} chn.handleError(err) } }() chn.chnMutex.Lock() defer chn.chnMutex.Unlock() if atomic.CompareAndSwapUint32(&chn.valid, 0, 0) { return false } chn.notifyChn <- notifyEvent{resourceID, clientID, event} mylog.GetErrorLogger().Println("Leave notify") return true }
func (r *Resourcer) Parse(proto *base.Proto) error { defer func() { if r := recover(); r != nil { } }() cmdID := proto.RD.BaseHD.CommandId & 0x7f if cmdID == base.OPEN_RESOURCE_CMD || cmdID == base.CLOSE_RESOURCE_CMD { r.ClientOpenChn <- proto.BD.Data } else if cmdID == base.DATA_STREAM { r.broadcastData(proto) } else { mylog.GetErrorLogger().Println("Now No Support CMD", cmdID) } return nil }
func main() { fmt.Println("DataTransfer Running!") server.ParseArg() right := base.VIDEO_RIGHT | base.AUDIO_RIGHT fmt.Println(right) var PKS1024 string = "s5DrLk2RE355BcO7FZ49xNdfAQtwKsMaEJa8yOnX7IjkRiOnmOoXCiCsRl0vpe23eZ7SWUW47DvQ1UxEpkGsFv/LOeOxMh06oXeH0zqlRPCw074q0s+IfRtcbdqGLvzvCz8ZAaoQrEIfwq2hm+7ueWKjWecqqQlQ5cu+dg3gd80=" var E string = "AQAB" base.InitRsaBig(PKS1024, E) stat.GetLocalStatistInst().Init("dt_llog", "logic.dat", 0) mylog.GetErrorLogger().Init("dt_elog", "error.log") go stat.StartMonitorTask("dt_mlog", "monitor.dat") go stat.GetLocalStatistInst().Start() runtime.GOMAXPROCS(runtime.NumCPU()) server.Run() exitChn := make(chan bool, 1) exit := <-exitChn fmt.Println("DataTransfer Running Over!", exit) }
func (r *Resourcer) Open(chn *ResourceClient, request *base.RequestJson, token *base.TokenJson) (string, string) { fmt.Println("1 Resourcer Open Resource ") r.mutex.Lock() defer r.mutex.Unlock() fmt.Println("2 Resourcer Open Resource ") /*verErr := r.verificate(token) if verErr != "" { return "", verErr }*/ if !atomic.CompareAndSwapUint32(&r.valid, 1, 1) { return "", base.NOFOUNF404 } if bytes.Equal([]byte(r.Error), []byte(base.OK)) { mylog.GetErrorLogger().Println("Resource Has Opend") r.attent(chn) return r.Result, r.Error } { proto := base.GetProto() proto.RD.BaseHD.CommandId = base.OPEN_RESOURCE_CMD proto.RD.HD.ClientIdent = r.DtClientID proto.RD.HD.ContextType = base.CONTEXT_JSON proto.RD.HD.TransferType = base.TRANSFER_RAW b, err := json.Marshal(request) if err != nil { mylog.GetErrorLogger().Println("Resource Open Json ", err) } proto.EncodeBody(b) if !r.SourceDataChn.ClientInf.Send(proto) { close(r.ClientOpenChn) r.ClientOpenChn = nil mylog.GetErrorLogger().Println("Resource Open Send Error ", err) return r.Result, base.NOFOUNF404 } } select { case msg, ok := <-r.ClientOpenChn: // msg只是包含数据 if !ok { mylog.GetErrorLogger().Println("ClientOpenChn Open ") return r.Result, base.NOFOUNF404 } var responseJson base.ResponseJson e := json.Unmarshal(msg[4:], &responseJson) if e != nil { mylog.GetErrorLogger().Println(e) return r.Result, base.PROTOERR400 } r.Result = strings.ToLower(responseJson.Result) r.Error = strings.ToLower(responseJson.Error) if strings.EqualFold(r.Error, base.OK) { r.attent(chn) } return r.Result, r.Error case <-time.After(20 * time.Second): //TimeOut return r.Result, base.NOFOUNF404 } return r.Result, r.Error }
func (r *Resourcer) Close(chn *ResourceClient, ns string, all bool) (string, string) { mylog.GetErrorLogger().Println("Close Resource") r.mutex.Lock() defer r.mutex.Unlock() mylog.GetErrorLogger().Println("Close unattent") openCount := r.unattent(chn, all) if openCount != 0 { return "", base.OK } { r.Result = "" r.Error = "" proto := base.GetProto() proto.RD.BaseHD.CommandId = base.CLOSE_RESOURCE_CMD proto.RD.HD.ClientIdent = r.SourceDataChn.ClientID proto.RD.HD.ContextType = base.CONTEXT_JSON proto.RD.HD.TransferType = base.TRANSFER_RAW /*todo 1. 生成token 2. */ var closeResParam = base.CloseResParamJson{r.GetID()} request := base.RequestJson{"", ns, "close", closeResParam} b, e := json.Marshal(request) if e != nil { mylog.GetErrorLogger().Println("Resource Close Json ", e) } proto.EncodeBody(b) if !r.SourceDataChn.ClientInf.Send(proto) { mylog.GetErrorLogger().Println("Resource Close Send Error ") return "", base.NOFOUNF404 } } select { case msg, ok := <-r.ClientOpenChn: fmt.Println("ClientOpenChn Close ") if !ok { mylog.GetErrorLogger().Println("ClientOpenChn Close ") return "", base.NOFOUNF404 } var responseJson base.ResponseJson e := json.Unmarshal(msg[4:], &responseJson) if e != nil { mylog.GetErrorLogger().Println("Resource Close ", e, string(msg[4:])) return r.Result, base.PROTOERR400 } return responseJson.Result, responseJson.Error case <-time.After(2 * time.Second): //TimeOut return r.Result, base.NOFOUNF404 } return r.Result, r.Error }
// 注册资源 func (chn *Channel) handleRegisterRes(clientID uint32, data []byte) { defer func() { if r := recover(); r != nil { chn.sendProto(clientID, base.REGISTER_RESOURCE, "", base.PROTOERR400, "huamail.defualt") chn.handleError(base.DTerror{"handleRegisterRes Panic"}) } }() var resourcer *Resourcer = nil request, _, err := chn.getReqParam(clientID, data[4:]) if err != nil { mylog.GetErrorLogger().Println("handleRegisterRes", err) chn.sendProto(clientID, base.REGISTER_RESOURCE, "", base.PROTOERR400, "huamai.default") return } param := request.Param.(map[string]interface{}) registerResParam := base.RegisterResParamJson{param["resourceid"].(string), uint32(param["restype"].(float64)), param["repos"].(bool)} resourceID := registerResParam.ID if CheckResourceIsExist(resourceID) { chn.sendProto(clientID, base.REGISTER_RESOURCE, "", base.EXISTRES_400, request.Ns) return } mylog.GetErrorLogger().Println("Register Source") resourcer = CreateResource(registerResParam.ID) if resourcer == nil { chn.sendProto(clientID, base.REGISTER_RESOURCE, "", base.INNERR_500, request.Ns) return } sourceDataChn := new(ResourceClient) sourceDataChn.ClientID = clientID sourceDataChn.ClientInf = chn resourcer.Register(sourceDataChn, registerResParam.ResType, registerResParam.RePos) func() { chn.resMutex.Lock() defer chn.resMutex.Unlock() chn.registerRes[registerResParam.ID] = resourcer }() chn.sendProto(clientID, base.REGISTER_RESOURCE, "", base.OK, request.Ns) fmt.Println("Resgitser OK") }
// 关注资源 func (r *Resourcer) attent(chn *ResourceClient) { r.ClientDataChn = append(r.ClientDataChn, chn) mylog.GetErrorLogger().Println(r.GetID(), " attent Resource Len ", len(r.ClientDataChn)) }
func (chn *Channel) handleReqOpenRes(clientID uint32, data []byte) { defer func() { if r := recover(); r != nil { chn.handleError(base.DTerror{"handleReqOpenResr Panic"}) } }() var responseErr string = "" var resourcer *Resourcer = nil var timeOut uint32 = 20 // 默认超时20s request, token, err := chn.getReqParam(clientID, data[4:]) if err != nil { chn.sendProto(clientID, base.OPEN_RESOURCE_CMD, "", err.Error(), "huamail.defualt") return } //获取资源 param := request.Param.(map[string]interface{}) openResParam := base.OpenResParamJson{param["resourceid"].(string), uint32(param["timeout"].(float64))} if chn.CheckResIsOpen(clientID) { chn.sendProto(clientID, base.OPEN_RESOURCE_CMD, "", base.OPEN303, "huamail.defualt") return } mylog.GetErrorLogger().Println("Chn Open Resource ID ", openResParam.ID) if openResParam.TimeOut < 120 { //当超时时间大于120s,设置超时为默认 timeOut = openResParam.TimeOut } for delayWait := uint32(0); delayWait < timeOut; delayWait++ { resourcer = GetResourcerByID(openResParam.ID) if resourcer != nil { break } time.Sleep(1 * time.Second) } if resourcer == nil { mylog.GetErrorLogger().Println("No Found Source ", openResParam.ID) chn.sendProto(clientID, base.OPEN_RESOURCE_CMD, "", base.NOFOUNF404, request.Ns) ReleaseResourcer(resourcer) return } clientDataID := new(ResourceClient) clientDataID.ClientInf = chn clientDataID.ClientID = clientID _, responseErr = resourcer.Open(clientDataID, request, token) responseJson := base.ResponseJson{request.Ns, request.Method, "", responseErr} b, err := json.Marshal(responseJson) if err != nil { mylog.GetErrorLogger().Println("handleOpenResource : ", err) ReleaseResourcer(resourcer) return } proto := new(base.Proto) proto.RD.BaseHD.CommandId = 0x80 | base.OPEN_RESOURCE_CMD proto.RD.HD.ClientIdent = clientID proto.EncodeBody(b) if !chn.Send(proto) { ReleaseResourcer(resourcer) return } if !strings.EqualFold(responseErr, base.OK) { ReleaseResourcer(resourcer) return } { chn.resMutex.Lock() defer chn.resMutex.Unlock() chn.openRes[clientID] = resourcer } stat.GetLocalStatistInst().OpenRes() }