diff --git a/business/jxstore/event/event.go b/business/jxstore/event/event.go index f47a6f85d..886945f4d 100644 --- a/business/jxstore/event/event.go +++ b/business/jxstore/event/event.go @@ -45,7 +45,7 @@ func init() { clientsHeart := make(map[string]*websocket.Conn) wsClient.Clients = clients wsClient.ClientsHeart = clientsHeart - wsClient.s = new(sync.RWMutex) + wsClient = new(sync.RWMutex) go handleMessages() } @@ -100,7 +100,7 @@ func ImMessage(userID string, ws *websocket.Conn) (err error) { if len(messageGroups) == 0 { return } - wsClient.s.Lock() + wsClient.Lock() clientUser[userID] = ws wsClient.ClientsHeart[userID] = ws for _, v := range messageGroups { @@ -110,7 +110,7 @@ func ImMessage(userID string, ws *websocket.Conn) (err error) { wsClient.Clients[v.GroupID] = clientUser } } - wsClient.s.Unlock() + wsClient.Unlock() globals.SugarLogger.Debugf("userID :%v ,clients :%v", userID, utils.Format4Output(wsClient.Clients, false)) var s *model.ImMessageRecord @@ -173,9 +173,9 @@ func ImMessage(userID string, ws *websocket.Conn) (err error) { } func GetOnlineUserCount() (count int) { - wsClient.s.RLock() + wsClient.RLock() count = len(wsClient.ClientsHeart) - wsClient.s.RUnlock() + wsClient.RUnlock() return count } diff --git a/business/jxstore/event/event_tcp.go b/business/jxstore/event/event_tcp.go index d375f2a20..b5007d150 100644 --- a/business/jxstore/event/event_tcp.go +++ b/business/jxstore/event/event_tcp.go @@ -11,131 +11,13 @@ import ( "git.rosy.net.cn/jx-callback/globals" "io" "net" - "regexp" "strconv" "strings" - "sync" "time" ) -const ( - heartText = "1e000f02000151" - printText = "1e00180200" - printSuccessText = "1e001802000150" - - printErrWithoutPaper = "05" - - printMsgAlreadySend = 2 //已经发出打印消息 - printMsgSuccess = 1 //打印成功 - printMsgWait = 0 //待打印 - printMsgFail = -1 //打印失败(打印机报出) - printMsgErr = -2 //京西报出 - printMsgAlreadyLoad = 3 //已放入队列 - - heartErrNormal = "00" //正常 - heartErrWithoutPaper = "04" //心跳错,缺纸 - heartErrHot = "08" //过热 - - printerStatusOnlineWithoutPaper = 2 //在线缺纸 - printerStatusOnline = 1 //在线 - printerStatusOffline = -1 //离线 - printerStatusOverFlow = -2 //流量超了 -) - -//标签 -const ( - signBR = "
" //换行 - signCenter = "
" //居中 - signLeft = "" //居左 - signRight = "" //居右 - signBig = "" //字体放大 - signHighBig = "" //字体纵向放大 - signWideBig = "" //字体横向放大 - signQrCenter = "" //二维码居中 - signQrLeft = "" //二维码居左 - signQrRight = "" //二维码居右 - signSound = "" //声音 - - hexSignBROrEXE = "0a" - hexSignCenter = "1b6101" - hexSignLeft = "1b6100" - hexSignRight = "1b6102" - hexSignNormal = "1b2100" - hexSignBig = "1b2130" - hexSignHighBig = "1b2110" - hexSignWideBig = "1b2120" - hexSignQrCenter = "1d5802" - hexSignQrLeft = "1d5800" - hexSignQrRight = "1d5804" - hexSignQr = "1b5a000106" //"1b5a000106" 0600 : 后面二维码的字节数 - hexSignQrEnd = "000a1b40" //000a0a0a1b40 - hexSignSound = "1d6b40" - - byteSignBR = "3c62723e" //换行 - byteSignCenter = "3c63656e7465723e" //居中 - byteSignLeft = "3c6c6566743e" //居左 - byteSignRight = "3c72696768743e" //居右 - byteSignBig = "3c623e" //字体放大 - byteSignHighBig = "3c68623e" //字体纵向放大 - byteSignWideBig = "3c77623e" //字体横向放大 - byteSignQrCenter = "3c7172633e" - byteSignQrLeft = "3c71726c3e" - byteSignQrRight = "3c7172723e" - byteSignSound = "3c736f756e643e" - - byteSignCenterE = "3c2f63656e7465723e" //居中 - byteSignLeftE = "3c2f6c6566743e" //居左 - byteSignRightE = "3c2f72696768743e" //居右 - byteSignBigE = "3c2f623e" //字体放大 - byteSignHighBigE = "3c2f68623e" //字体纵向放大 - byteSignWideBigE = "3c2f77623e" //字体横向放大 - byteSignQrCenterE = "3c2f7172633e" - byteSignQrLeftE = "3c2f71726c3e" - byteSignQrRightE = "3c2f7172723e" - byteSignSoundE = "3c2f736f756e643e" -) - -var ( - tcpClient = &TcpClient{} - - printErrMap = map[string]string{ - printErrWithoutPaper: "打印机缺纸!", - } - - signMap = map[string]string{ - byteSignBR: hexSignBROrEXE, - } - - regexpQrc = regexp.MustCompile(byteSignQrCenter + "(.*?)" + byteSignQrCenterE) - regexpQrl = regexp.MustCompile(byteSignQrLeft + "(.*?)" + byteSignQrLeftE) - regexpQrr = regexp.MustCompile(byteSignQrRight + "(.*?)" + byteSignQrRightE) - regexpSound = regexp.MustCompile(byteSignSound + "(.*?)" + byteSignSoundE) - - printMsgChan = make(chan *model.PrintMsg, 1024) - printMsgCallbackChan = make(chan string, 1024) - printMsgChanFail = make(chan *model.PrintMsg) -) - -type PrintInfo struct { - C net.Conn - Status int // 2 //在线缺纸 1 //在线 -1 //离线 - StatusTime time.Time -} - -//连接的客户端,吧每个客户端都放进来 -type TcpClient struct { - Clients map[string]*PrintInfo - s *sync.RWMutex -} - -type GetPrintStatus struct { - PrintNo string //打印机编号 - AppID int -} - func ListenTcp() { - tcpClient.Clients = make(map[string]*PrintInfo) - tcpClient.s = new(sync.RWMutex) + t := NewTcpClient() l, err := net.Listen("tcp", ":8000") if err != nil { fmt.Println("listen error:", err) @@ -143,20 +25,20 @@ func ListenTcp() { } globals.SugarLogger.Debugf("begin listenTcp port 8000......") go HandleTcpMessages() - go HandleCheckTcpHeart() - go doPrint2(printMsgChan) - //go doPrint(printMsgChanFail) + go t.HandleCheckTcpHeart() + go t.doPrint2(printMsgChan) + go t.doPrint(printMsgChanFail) for { c, err := l.Accept() if err != nil { fmt.Println("accept error:", err) break } - go handleConn(c) + go t.handleConn(c) } } -func handleConn(c net.Conn) { +func (t *TcpClient) handleConn(c net.Conn) { var ( printNo string //打印机编号 printStatus *GetPrintStatus @@ -181,13 +63,13 @@ func handleConn(c net.Conn) { if err = json.Unmarshal(buffer[:n], &printStatus); err == nil { fmt.Println("handleConn msg: ", string(buffer[:n])) if printStatus != nil { - var status int - if tcpClient.Clients[printStatus.PrintNo] != nil { - status = tcpClient.Clients[printStatus.PrintNo].Status - } else { - status = printerStatusOffline - } - globals.SugarLogger.Debugf("handleConn getstatus :%v", utils.Format4Output(tcpClient.Clients[printStatus.PrintNo], true)) + status := t.getPrintStatus(printStatus.PrintNo) + //if t.Clients[printStatus.PrintNo] != nil { + // status = t.Clients[printStatus.PrintNo].Status + //} else { + // status = printerStatusOffline + //} + //globals.SugarLogger.Debugf("handleConn getstatus :%v", utils.Format4Output(t.Clients[printStatus.PrintNo], true)) c.Write([]byte(utils.Int2Str(status))) c.Close() } @@ -201,30 +83,34 @@ func handleConn(c net.Conn) { printNo = string(printNoData) globals.SugarLogger.Debugf("handleConn printno :[%v]", printNo) status := printStatus2JxStatus(data[len(data)-8 : len(data)-6]) - if tcpClient.Clients[printNo] == nil { - printInfo := &PrintInfo{ - C: c, - Status: printStatus2JxStatus(data[len(data)-8 : len(data)-6]), - StatusTime: time.Now(), - } - tcpClient.s.Lock() - tcpClient.Clients[printNo] = printInfo - tcpClient.s.Unlock() + if t.Clients[printNo] == nil { + //printInfo := &PrintInfo{ + // C: c, + // Status: printStatus2JxStatus(data[len(data)-8 : len(data)-6]), + // StatusTime: time.Now(), + //} + //t.Lock() + //t.Clients[printNo] = printInfo + //t.Unlock() + t.addConn(c, printNo, printStatus2JxStatus(data[len(data)-8:len(data)-6])) changePrinterStatus(printNo, status) - if status > 0 { - //printFail() + if status == printerStatusOnline { + printFail() } } else { //改变打印机状态 - tcpClient.s.Lock() + //t.Lock() + //if t.Clients[printNo] != nil { + // if t.Clients[printNo].Status != status { + // t.Clients[printNo].Status = status + // } + // t.Clients[printNo].StatusTime = time.Now() + //} + //t.Unlock() changePrinterStatus(printNo, status) - if tcpClient.Clients[printNo] != nil { - if tcpClient.Clients[printNo].Status != status { - tcpClient.Clients[printNo].Status = status - } - tcpClient.Clients[printNo].StatusTime = time.Now() + if t.getPrintStatus(printNo) != status { + t.setPrintStatus(printNo, status) } - tcpClient.s.Unlock() } } else if strings.Contains(data, printText) { globals.SugarLogger.Debugf("handleConn print callback: %v", data) @@ -265,16 +151,14 @@ func printFail() (err error) { var ( db = dao.GetDB() ) - prints, _ := dao.GetPrintMsgs(db, []int{printMsgWait, printMsgFail, printMsgErr}, time.Now().Add(-time.Hour*3), time.Now(), 0, 999) + prints, _ := dao.GetPrintMsgs(db, []int{printMsgWait, printMsgFail, printMsgErr, printMsgAlreadyLoad, printMsgAlreadySend}, time.Now().Add(-time.Hour*3), time.Now(), 0, 999) for _, printMsg := range prints { - //printMsgChanFail <- printMsg - printMsg.Status = printMsgAlreadyLoad - dao.UpdateEntity(db, printMsg, "Status") + printMsgChanFail <- printMsg } return err } -func doPrint(printMsgChanFail chan *model.PrintMsg) (err error) { +func (t *TcpClient) doPrint(printMsgChanFail chan *model.PrintMsg) (err error) { var ( db = dao.GetDB() ) @@ -287,25 +171,25 @@ func doPrint(printMsgChanFail chan *model.PrintMsg) (err error) { ) if printMsg != nil { if err = checkPrintMsg(db, printMsg); err == nil { - tcpClient.s.RLock() - if tcpClient.Clients[printMsg.PrintNo] != nil { - if tcpClient.Clients[printMsg.PrintNo].Status == printerStatusOnline { - if tcpClient.Clients[printMsg.PrintNo].C != nil { - c = tcpClient.Clients[printMsg.PrintNo].C - data, err = buildMsg(printMsg) - } - } - } - tcpClient.s.RUnlock() - if c != nil { + //t.Lock() + //if t.Clients[printMsg.PrintNo] != nil { + // if t.Clients[printMsg.PrintNo].Status == printerStatusOnline { + // if t.Clients[printMsg.PrintNo].C != nil { + // c = t.Clients[printMsg.PrintNo].C + // data, err = buildMsg(printMsg) + // } + // } + //} + //t.Unlock() + if c = t.getPrintConn(printMsg.PrintNo); c != nil { + data, err = buildMsg(printMsg) if _, err = c.Write(data); err != nil { globals.SugarLogger.Debugf("handleTcpMessages err [%v]", err) - delete(tcpClient.Clients, printMsg.PrintNo) - c.Close() + t.delConn(printMsg.PrintNo) + //delete(t.Clients, printMsg.PrintNo) + //c.Close() } else { globals.SugarLogger.Debugf("handleTcpMessages success, data: %v", hex.EncodeToString(data)) - printMsg.Status = printMsgAlreadySend - dao.UpdateEntity(db, printMsg, "Status", "Comment") } } } @@ -323,7 +207,7 @@ func printStatus2JxStatus(printStatus string) (status int) { return status } -func changePrintMsg(data string) (err error) { +func (t *TcpClient) changePrintMsg(data string) (err error) { var ( db = dao.GetDB() printNo, comment string @@ -343,7 +227,7 @@ func changePrintMsg(data string) (err error) { status = printMsgFail comment = printErrMap[data[12:14]] } - if tcpClient.Clients[printNo] == nil { + if !t.isExist(printNo) { return err } if printMsgs, err := dao.GetPrintMsgNoPage(db, printNo, orderNo); err != nil { @@ -377,7 +261,7 @@ func HandleTcpMessages() { } } -func doPrint2(printMsgChan chan *model.PrintMsg) (err error) { +func (t *TcpClient) doPrint2(printMsgChan chan *model.PrintMsg) (err error) { var ( db = dao.GetDB() ) @@ -390,20 +274,33 @@ func doPrint2(printMsgChan chan *model.PrintMsg) (err error) { ) if printMsg != nil { if err = checkPrintMsg(db, printMsg); err == nil { - tcpClient.s.RLock() - if tcpClient.Clients[printMsg.PrintNo] != nil { - if tcpClient.Clients[printMsg.PrintNo].Status == printerStatusOnline { - if tcpClient.Clients[printMsg.PrintNo].C != nil { - c = tcpClient.Clients[printMsg.PrintNo].C - data, err = buildMsg(printMsg) - } - } else if tcpClient.Clients[printMsg.PrintNo].Status == printerStatusOffline { - err = fmt.Errorf("打印机离线!") - } else if tcpClient.Clients[printMsg.PrintNo].Status == printerStatusOnlineWithoutPaper { - err = fmt.Errorf("打印机缺纸!") + //t.Lock() + //if t.Clients[printMsg.PrintNo] != nil { + // if t.Clients[printMsg.PrintNo].Status == printerStatusOnline { + // if t.Clients[printMsg.PrintNo].C != nil { + // c = t.Clients[printMsg.PrintNo].C + // data, err = buildMsg(printMsg) + // } + // } else if t.Clients[printMsg.PrintNo].Status == printerStatusOffline { + // err = fmt.Errorf("打印机离线!") + // } else if t.Clients[printMsg.PrintNo].Status == printerStatusOnlineWithoutPaper { + // err = fmt.Errorf("打印机缺纸!") + // } + //} + //t.Unlock() + status := t.getPrintStatus(printMsg.PrintNo) + switch status { + case printerStatusOnline: + if c = t.getPrintConn(printMsg.PrintNo); c != nil { + data, err = buildMsg(printMsg) } + case printerStatusOffline: + err = fmt.Errorf("打印机离线!") + case printerStatusOnlineWithoutPaper: + err = fmt.Errorf("打印机缺纸!") + default: + err = fmt.Errorf("打印机状态未知!") } - tcpClient.s.RUnlock() } } else { err = fmt.Errorf("未查询到此printMsg") @@ -412,22 +309,24 @@ func doPrint2(printMsgChan chan *model.PrintMsg) (err error) { printMsg.Status = printMsgErr printMsg.Comment = err.Error() dao.UpdateEntity(db, printMsg, "Status", "Comment") - delete(tcpClient.Clients, printMsg.PrintNo) - if c != nil { - c.Close() - } + t.delConn(printMsg.PrintNo) + //delete(t.Clients, printMsg.PrintNo) + //if c != nil { + // c.Close() + //} } else { if c != nil { if _, err = c.Write(data); err != nil { globals.SugarLogger.Debugf("handleTcpMessages err [%v]", err) - delete(tcpClient.Clients, printMsg.PrintNo) - c.Close() + t.delConn(printMsg.PrintNo) + //delete(t.Clients, printMsg.PrintNo) + //c.Close() } else { globals.SugarLogger.Debugf("handleTcpMessages success, data: %v", hex.EncodeToString(data)) printMsg.Status = printMsgAlreadySend dao.UpdateEntity(db, printMsg, "Status", "Comment") dataStr := <-printMsgCallbackChan - changePrintMsg(dataStr) + t.changePrintMsg(dataStr) } } } @@ -436,10 +335,10 @@ func doPrint2(printMsgChan chan *model.PrintMsg) (err error) { return err } -func HandleCheckTcpHeart() { +func (t *TcpClient) HandleCheckTcpHeart() { for { keys := []string{} - for k, v := range tcpClient.Clients { + for k, v := range t.Clients { if time.Now().Sub(v.StatusTime) > time.Minute+time.Second { v.Status = printerStatusOffline keys = append(keys, k) @@ -447,8 +346,8 @@ func HandleCheckTcpHeart() { } for _, v := range keys { changePrinterStatus(v, printerStatusOffline) - if tcpClient.Clients[v] != nil { - delete(tcpClient.Clients, v) + if t.Clients[v] != nil { + delete(t.Clients, v) } } } diff --git a/business/jxstore/event/event_tcp_utils.go b/business/jxstore/event/event_tcp_utils.go new file mode 100644 index 000000000..4d51048bf --- /dev/null +++ b/business/jxstore/event/event_tcp_utils.go @@ -0,0 +1,189 @@ +package event + +import ( + "git.rosy.net.cn/jx-callback/business/model" + "net" + "regexp" + "sync" + "time" +) + +const ( + heartText = "1e000f02000151" + printText = "1e00180200" + printSuccessText = "1e001802000150" + + printErrWithoutPaper = "05" + + printMsgAlreadySend = 2 //已经发出打印消息 + printMsgSuccess = 1 //打印成功 + printMsgWait = 0 //待打印 + printMsgFail = -1 //打印失败(打印机报出) + printMsgErr = -2 //京西报出 + printMsgAlreadyLoad = 3 //已放入队列 + + heartErrNormal = "00" //正常 + heartErrWithoutPaper = "04" //心跳错,缺纸 + heartErrHot = "08" //过热 + + printerStatusOnlineWithoutPaper = 2 //在线缺纸 + printerStatusOnline = 1 //在线 + printerStatusOffline = -1 //离线 +) + +//标签 +const ( + signBR = "
" //换行 + signCenter = "
" //居中 + signLeft = "" //居左 + signRight = "" //居右 + signBig = "" //字体放大 + signHighBig = "" //字体纵向放大 + signWideBig = "" //字体横向放大 + signQrCenter = "" //二维码居中 + signQrLeft = "" //二维码居左 + signQrRight = "" //二维码居右 + signSound = "" //声音 + + hexSignBROrEXE = "0a" + hexSignCenter = "1b6101" + hexSignLeft = "1b6100" + hexSignRight = "1b6102" + hexSignNormal = "1b2100" + hexSignBig = "1b2130" + hexSignHighBig = "1b2110" + hexSignWideBig = "1b2120" + hexSignQrCenter = "1d5802" + hexSignQrLeft = "1d5800" + hexSignQrRight = "1d5804" + hexSignQr = "1b5a000106" //"1b5a000106" 0600 : 后面二维码的字节数 + hexSignQrEnd = "000a1b40" //000a0a0a1b40 + hexSignSound = "1d6b40" + + byteSignBR = "3c62723e" //换行 + byteSignCenter = "3c63656e7465723e" //居中 + byteSignLeft = "3c6c6566743e" //居左 + byteSignRight = "3c72696768743e" //居右 + byteSignBig = "3c623e" //字体放大 + byteSignHighBig = "3c68623e" //字体纵向放大 + byteSignWideBig = "3c77623e" //字体横向放大 + byteSignQrCenter = "3c7172633e" + byteSignQrLeft = "3c71726c3e" + byteSignQrRight = "3c7172723e" + byteSignSound = "3c736f756e643e" + + byteSignCenterE = "3c2f63656e7465723e" //居中 + byteSignLeftE = "3c2f6c6566743e" //居左 + byteSignRightE = "3c2f72696768743e" //居右 + byteSignBigE = "3c2f623e" //字体放大 + byteSignHighBigE = "3c2f68623e" //字体纵向放大 + byteSignWideBigE = "3c2f77623e" //字体横向放大 + byteSignQrCenterE = "3c2f7172633e" + byteSignQrLeftE = "3c2f71726c3e" + byteSignQrRightE = "3c2f7172723e" + byteSignSoundE = "3c2f736f756e643e" +) + +var ( + //t = &TcpClient{} + + printErrMap = map[string]string{ + printErrWithoutPaper: "打印机缺纸!", + } + + signMap = map[string]string{ + byteSignBR: hexSignBROrEXE, + } + + regexpQrc = regexp.MustCompile(byteSignQrCenter + "(.*?)" + byteSignQrCenterE) + regexpQrl = regexp.MustCompile(byteSignQrLeft + "(.*?)" + byteSignQrLeftE) + regexpQrr = regexp.MustCompile(byteSignQrRight + "(.*?)" + byteSignQrRightE) + regexpSound = regexp.MustCompile(byteSignSound + "(.*?)" + byteSignSoundE) + + printMsgChan = make(chan *model.PrintMsg, 1024) + printMsgCallbackChan = make(chan string, 1024) + printMsgChanFail = make(chan *model.PrintMsg) +) + +type PrintInfo struct { + C net.Conn + Status int // 2 //在线缺纸 1 //在线 -1 //离线 + StatusTime time.Time +} + +//连接的客户端,吧每个客户端都放进来 +type TcpClient struct { + Clients map[string]*PrintInfo + *sync.RWMutex +} + +type GetPrintStatus struct { + PrintNo string //打印机编号 + AppID int +} + +func (t *TcpClient) delConn(key string) { + t.Lock() + defer t.Unlock() + + delete(t.Clients, key) + t.Clients[key].C.Close() +} + +func (t *TcpClient) addConn(c net.Conn, key string, status int) { + t.Lock() + defer t.Unlock() + + t.Clients[key] = &PrintInfo{ + C: c, + Status: status, + StatusTime: time.Now(), + } +} + +func (t *TcpClient) getPrintStatus(key string) int { + t.RLock() + defer t.RUnlock() + if t.isExist(key) { + return t.Clients[key].Status + } else { + return printerStatusOffline + } +} + +func (t *TcpClient) getPrintConn(key string) net.Conn { + t.RLock() + defer t.RUnlock() + if t.isExist(key) { + return t.Clients[key].C + } else { + return nil + } +} + +func (t *TcpClient) isExist(key string) bool { + t.RLock() + defer t.RUnlock() + + if t.Clients[key] == nil { + return false + } else { + return true + } +} + +func (t *TcpClient) setPrintStatus(key string, status int) { + t.Lock() + defer t.Unlock() + + if t.isExist(key) { + t.Clients[key].Status = status + t.Clients[key].StatusTime = time.Now() + } +} + +func NewTcpClient() *TcpClient { + return &TcpClient{ + Clients: make(map[string]*PrintInfo), + } +}