diff --git a/business/jxstore/event/event_tcp.go b/business/jxstore/event/event_tcp.go index e5b81c72c..170ce3f85 100644 --- a/business/jxstore/event/event_tcp.go +++ b/business/jxstore/event/event_tcp.go @@ -53,7 +53,7 @@ func (t *TcpClient) handleConn(c net.Conn) { } return } - //也可能是查状态的 + //也可能是查状态的(openAPI外部查询,一次性的) if err = json.Unmarshal(buffer[:n], &printStatus); err == nil { fmt.Println("handleConn msg: ", string(buffer[:n])) if printStatus != nil { @@ -62,7 +62,7 @@ func (t *TcpClient) handleConn(c net.Conn) { c.Close() } } - //看是心跳还是打印返回 + //看是心跳还是打印回调 data := hex.EncodeToString(buffer[:n]) //证明是心跳 if strings.Contains(data, heartText) { @@ -71,6 +71,13 @@ func (t *TcpClient) handleConn(c net.Conn) { printNo = string(printNoData) globals.SugarLogger.Debugf("handleConn printno :[%v]", printNo) status := printStatus2JxStatus(data[len(data)-8 : len(data)-6]) + //如果没在连接池里 + //1、加到连接池中,不同的打印机no开不同的go + //2、初始化channel,每个打印机一个,放打印消息和打印回调消息 + //3、读数据库里的待打印信息,放到打印channel中 + //4、读打印channel并打印,并切等待回调channel中的消息 + //5、修改数据库中打印机状态(没在连接池中说明是重新连接的) + //6、监听心跳时间,超过2分钟就clear掉 if t.Clients[printNo] == nil { t.addConn(c, printNo, status) t.buildCallBackMap(printNo) @@ -83,15 +90,19 @@ func (t *TcpClient) handleConn(c net.Conn) { changePrinterStatus(printNo, status) t.HandleCheckTcpHeart(printNo) } else { + //在加到连接池中已经更新了时间,所以放在else里 t.setPrintStatusTime(printNo) } + //状态不一致再更新状态(可能缺纸了,过热了等) if t.getPrintStatus(printNo) != status { t.setPrintStatus(printNo, status) changePrinterStatus(printNo, status) } globals.SugarLogger.Debugf("handleConn print model %v", utils.Format4Output(t.Clients[printNo], true)) - } else if strings.Contains(data, printText) { + } else if strings.Contains(data, printText) { //打印回调 globals.SugarLogger.Debugf("handleConn print callback: %v", data) + //打印消息发送后,打印机会回调该条打印消息的状态(打印成功or失败,失败原因..) + //将回调的信息放到回调channel中,打印成功后再打印下一条消息 _, printNo = getCallbackMsgInfo(data) t.addCallbackChan(printNo, data) } @@ -117,15 +128,17 @@ func (t *TcpClient) changePrintMsg(data string, orderNo int64, printNo string) ( status int ) //1、先找出打印机编号和订单序列号,这两个确定唯一一条消息? + //通过参数传进来 //2、打印成功改变打印表的状态 if strings.Contains(data, printSuccessText) { - //1e001802000150323032313036313530303030313000013c + //1e001802000150323032313036313530303030313000013c 成功消息例子 status = printMsgSuccess } else { //打印失败也改变状态并更新失败原因 status = printMsgFail comment = printErrMap[data[12:14]] } + //这里序号重复会有问题 if printMsgs, err := dao.GetPrintMsgNoPage(db, printNo, orderNo); err != nil { globals.SugarLogger.Debugf("changePrintMsg err :[%v]", err) return err @@ -152,12 +165,18 @@ func (t *TcpClient) HandleTcpMessages(printNo string) { globals.SugarLogger.Debugf("build HandleTcpMessages printNo: %s", printNo) go func() { for { - //一直读? - prints, _ := dao.GetPrintMsgs(db, printNo, []int{printMsgWait}, time.Now().Add(-time.Hour*3), time.Now(), offset, pageSize) - for _, printMsg := range prints { - printMsg.Status = printMsgAlreadyLoad - if _, err := dao.UpdateEntity(db, printMsg, "Status"); err == nil { - t.addMsgChan(printMsg) + select { + case <-timeoutChan: + return + default: + //一直读? + prints, _ := dao.GetPrintMsgs(db, printNo, []int{printMsgWait}, time.Now().Add(-time.Hour*3), time.Now(), offset, pageSize) + for _, printMsg := range prints { + printMsg.Status = printMsgAlreadyLoad + //先避免重复读再插到channel? + if _, err := dao.UpdateEntity(db, printMsg, "Status"); err == nil { + t.addMsgChan(printMsg) + } } } } @@ -175,7 +194,13 @@ func (t *TcpClient) doPrint(key string) (err error) { go func() { for { select { - case printMsg := <-t.MsgMap[key]: + case <-timeoutChan: + return + default: + printMsg, ok := <-t.MsgMap[key] + if !ok { + return + } var ( data []byte c net.Conn @@ -184,6 +209,7 @@ func (t *TcpClient) doPrint(key string) (err error) { if err = checkPrintMsg(db, printMsg); err == nil { status := t.getPrintStatus(printMsg.PrintNo) switch status { + //只有在线才打印内容 case printerStatusOnline: if c = t.getPrintConn(printMsg.PrintNo); c != nil { data, err = buildMsg(printMsg) @@ -209,6 +235,7 @@ func (t *TcpClient) doPrint(key string) (err error) { t.delConn(printMsg.PrintNo) } else { globals.SugarLogger.Debugf("handleTcpMessages success, data: %v", hex.EncodeToString(data)) + //等待回调 dataStr := <-t.CallBackMap[printMsg.PrintNo] a, b := getCallbackMsgInfo(dataStr) t.changePrintMsg(dataStr, a, b) @@ -233,6 +260,7 @@ func (t *TcpClient) HandleCheckTcpHeart(key string) { if t.isExist(key) { globals.SugarLogger.Debugf("HandleCheckTcpHeart del key,%v", key) t.clear(key) + timeoutChan <- 1 return } } diff --git a/business/jxstore/event/event_tcp_utils.go b/business/jxstore/event/event_tcp_utils.go index a8333b2bc..77a008b8f 100644 --- a/business/jxstore/event/event_tcp_utils.go +++ b/business/jxstore/event/event_tcp_utils.go @@ -68,6 +68,7 @@ const ( hexSignQrEnd = "000a1b40" //000a0a0a1b40 hexSignSound = "1d6b40" + //起始标签 byteSignBR = "3c62723e" //换行 byteSignCenter = "3c63656e7465723e" //居中 byteSignLeft = "3c6c6566743e" //居左 @@ -80,6 +81,7 @@ const ( byteSignQrRight = "3c7172723e" byteSignSound = "3c736f756e643e" + //结束标签 byteSignCenterE = "3c2f63656e7465723e" //居中 byteSignLeftE = "3c2f6c6566743e" //居左 byteSignRightE = "3c2f72696768743e" //居右 @@ -106,7 +108,7 @@ var ( regexpQrr = regexp.MustCompile(byteSignQrRight + "(.*?)" + byteSignQrRightE) regexpSound = regexp.MustCompile(byteSignSound + "(.*?)" + byteSignSoundE) - timeoutChan = make(chan int, 10) + timeoutChan = make(chan int) ) type PrintInfo struct { @@ -326,6 +328,7 @@ func changePrinterStatus(printNo string, status int) { } } +//按打印机方提供的文档来的 func buildMsg(printMsg *model.PrintMsg) (data []byte, err error) { var ( content = printMsg.Content @@ -349,6 +352,7 @@ func buildMsg(printMsg *model.PrintMsg) (data []byte, err error) { return jxutils.Hextob(dataStr + check), err } +//替换特殊字符,上面那个hextob转不了,先替换一下 func replaceContentOther(content string) string { return strings.ReplaceAll(content, "⃣️", " ") }