1
This commit is contained in:
@@ -4,12 +4,15 @@ import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.rosy.net.cn/baseapi/utils"
|
||||
"git.rosy.net.cn/jx-callback/business/model"
|
||||
"git.rosy.net.cn/jx-callback/business/model/dao"
|
||||
"git.rosy.net.cn/jx-print/globals"
|
||||
"git.rosy.net.cn/jx-callback/globals"
|
||||
"io"
|
||||
"net"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// ConnRead 获取链接数据
|
||||
@@ -43,7 +46,7 @@ func ListenTcp() {
|
||||
}
|
||||
}()
|
||||
|
||||
if err = handleConn(c); err != nil {
|
||||
if err := handleConn(c); err != nil {
|
||||
c.Close()
|
||||
Pool.Wait()
|
||||
Pool.Stop()
|
||||
@@ -60,30 +63,42 @@ func handleConn(c net.Conn) error {
|
||||
}
|
||||
for {
|
||||
buffer, n, err := ConnRead(c)
|
||||
|
||||
//remoteAddr := c.RemoteAddr().(*net.TCPAddr)
|
||||
//remoteIP := remoteAddr.IP.String() // 打印机IP
|
||||
//remotePort := remoteAddr.Port // 打印机端口
|
||||
//globals.SugarLogger.Debugf("remoteIP1: %s", remoteIP)
|
||||
//globals.SugarLogger.Debugf("remotePort1: %d", remotePort)
|
||||
|
||||
// 重连
|
||||
printRemoteAddr := c.RemoteAddr().String()
|
||||
printRemoteAddr = strings.Split(printRemoteAddr, ":")[0]
|
||||
printNoByIP, _ := PrintAddrAndIp.GetPrintAddrAndIp(printRemoteAddr)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
fmt.Println("connection close")
|
||||
} else {
|
||||
fmt.Println("ReadString err:", err)
|
||||
}
|
||||
globals.SugarLogger.Debugf("--------printRemoteAddr := %s,printNo := %s", printRemoteAddr, printNoByIP)
|
||||
if printNo, ok := PrintAddrAndIp.GetPrintAddrAndIp(printRemoteAddr); ok {
|
||||
PrintAddrAndIp.DelPrintAddrAndIp(printRemoteAddr)
|
||||
PrintObject.DelPrintObj(printNo)
|
||||
PrintIpAndAddr.DelPrintIpAndAddr(printRemoteAddr)
|
||||
dao.ExecuteSQL(dao.GetDB(), `UPDATE printer SET status = -1,is_online = -1 WHERE print_no = ? `, []interface{}{printNo}...)
|
||||
} else {
|
||||
printStatusOff := make(map[string]int, 0)
|
||||
for ip, pn := range PrintAddrAndIp.PrintObject {
|
||||
if ip == printRemoteAddr {
|
||||
PrintAddrAndIp.DelPrintAddrAndIp(printRemoteAddr)
|
||||
PrintIpAndAddr.DelPrintIpAndAddr(pn)
|
||||
PrintObject.DelPrintObj(printNo)
|
||||
} else if pn != "" {
|
||||
printStatusOff[pn] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
//看是心跳还是打印回调
|
||||
data := hex.EncodeToString(buffer[:n])
|
||||
var (
|
||||
printNo string = "" //打印机编号
|
||||
heartbeat bool = false
|
||||
callback bool = false
|
||||
t *TcpClient = nil
|
||||
printNo string = "" //打印机编号
|
||||
heartbeat bool = false
|
||||
callback bool = false
|
||||
)
|
||||
if strings.Contains(data, heartText) || strings.Contains(data, heartTextNew) {
|
||||
printNoData, _ := hex.DecodeString(data[len(heartText) : len(data)-8])
|
||||
@@ -93,19 +108,15 @@ func handleConn(c net.Conn) error {
|
||||
_, printNo = getCallbackMsgInfo(data)
|
||||
callback = true
|
||||
}
|
||||
globals.SugarLogger.Debugf("printNoData------: %s", printNo)
|
||||
|
||||
t = NewTcpClient()
|
||||
TcpClientList.Delete(printNo)
|
||||
TcpClientList.Store(printNo, t)
|
||||
//if value, have := TcpClientList.Load(printNo); !have {
|
||||
// TcpClientList.Store(printNo, t)
|
||||
//} else {
|
||||
// t = value.(*TcpClient)
|
||||
//}
|
||||
t, ok := PrintObject.GetPrintObj(printNo)
|
||||
if !ok || t.Clients[printNo] == nil || time.Now().Sub(t.Clients[printNo].StatusTime).Seconds() >= 120 {
|
||||
t = NewTcpClient()
|
||||
}
|
||||
|
||||
if heartbeat {
|
||||
// 证明是心跳
|
||||
Heartbeat(c, t, data, printNo, "")
|
||||
Heartbeat(c, t, data, printNo, printRemoteAddr)
|
||||
} else if callback {
|
||||
// 打印回调
|
||||
Callback(c, t, data, printNo)
|
||||
@@ -125,8 +136,238 @@ func (t *TcpClient) printFail() (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *TcpClient) changePrintMsg(data string, orderNo int64, printNo string) (err error) {
|
||||
var (
|
||||
db = dao.GetDB()
|
||||
comment string
|
||||
status int
|
||||
)
|
||||
//1、先找出打印机编号和订单序列号,这两个确定唯一一条消息?
|
||||
//通过参数传进来
|
||||
//2、打印成功改变打印表的状态
|
||||
if strings.Contains(data, printSuccessText) || strings.Contains(data, printSuccessTextNew) {
|
||||
status = printMsgSuccess
|
||||
comment = "回调成功,修改打印状态"
|
||||
} 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
|
||||
} else if len(printMsgs) == 0 {
|
||||
globals.SugarLogger.Debugf("changePrintMsg err ,not found printMsg printNo:[%v], orderNo :[%v]", printNo, orderNo)
|
||||
} else if len(printMsgs) > 0 {
|
||||
for _, v := range printMsgs {
|
||||
v.Comment = comment
|
||||
v.Status = status
|
||||
dao.UpdateEntity(db, v, "Comment", "Status")
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func HandleTcpMessages(t *TcpClient, printNo string) {
|
||||
var (
|
||||
db = dao.GetDB()
|
||||
offset, pageSize = 0, 10
|
||||
)
|
||||
if !t.isExistMsg(printNo) {
|
||||
return
|
||||
}
|
||||
|
||||
fn := func() {
|
||||
//for {
|
||||
// time.Sleep(2 * time.Second)
|
||||
if t.TimeoutMap[printNo] == true {
|
||||
timeNow := time.Now()
|
||||
timeStart := time.Date(timeNow.Year(), timeNow.Month(), timeNow.Day(), 0, 0, 0, 0, timeNow.Location())
|
||||
timeEnd := time.Date(timeNow.Year(), timeNow.Month(), timeNow.Day(), 23, 59, 59, 0, timeNow.Location())
|
||||
prints, _ := dao.GetPrintMsgs(db, printNo, []int{PrintMsgWait}, timeStart.AddDate(0, 0, -1), timeEnd, offset, pageSize)
|
||||
for _, printMsg := range prints {
|
||||
printMsg.Status = PrintMsgAlreadyLoad
|
||||
//先避免重复读再插到channel?
|
||||
if _, err := dao.UpdateEntity(db, printMsg, "Status"); err == nil {
|
||||
if err = t.addMsgChan(printMsg); err != nil {
|
||||
globals.SugarLogger.Debugf("HandleTcpMessages addMsgChan Err: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
globals.SugarLogger.Debugf("HandleTcpMessages timeout")
|
||||
return
|
||||
}
|
||||
}
|
||||
Pool.AddJob(fn)
|
||||
}
|
||||
|
||||
func (t *TcpClient) readTimeoutMap(key string) bool {
|
||||
t.Lock()
|
||||
defer t.Unlock()
|
||||
return t.TimeoutMap[key]
|
||||
}
|
||||
|
||||
func doPrint(t *TcpClient, key string) (err error) {
|
||||
var (
|
||||
db = dao.GetDB()
|
||||
)
|
||||
|
||||
if !t.isExistMsg(key) {
|
||||
return err
|
||||
}
|
||||
|
||||
fn := func() {
|
||||
for {
|
||||
if t.TimeoutMap[key] == true {
|
||||
select {
|
||||
case printMsg, ok := <-t.MsgMap[key]:
|
||||
if !ok {
|
||||
globals.SugarLogger.Debugf("doPrint err !ok ...")
|
||||
return
|
||||
}
|
||||
var (
|
||||
data []byte
|
||||
c net.Conn
|
||||
)
|
||||
if printMsg == nil {
|
||||
globals.SugarLogger.Debugf("print msg is nil")
|
||||
continue
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
case printerStatusOffline:
|
||||
err = fmt.Errorf("打印机离线!")
|
||||
case printerStatusOnlineWithoutPaper:
|
||||
err = fmt.Errorf("打印机缺纸!")
|
||||
default:
|
||||
err = fmt.Errorf("打印机状态未知!")
|
||||
}
|
||||
}
|
||||
|
||||
if c == nil {
|
||||
if printRemoteAddrIP, have := PrintIpAndAddr.GetPrintIpAndAddr(key); have {
|
||||
PrintIpAndAddr.DelPrintIpAndAddr(key)
|
||||
PrintAddrAndIp.DelPrintAddrAndIp(printRemoteAddrIP)
|
||||
PrintObject.DelPrintObj(key)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
printMsg.Status = printMsgErr
|
||||
printMsg.Comment = err.Error()
|
||||
dao.UpdateEntity(db, printMsg, "Status", "Comment")
|
||||
|
||||
if printRemoteAddrIP, have := PrintIpAndAddr.GetPrintIpAndAddr(key); have {
|
||||
PrintIpAndAddr.DelPrintIpAndAddr(key)
|
||||
PrintAddrAndIp.DelPrintAddrAndIp(printRemoteAddrIP)
|
||||
PrintObject.DelPrintObj(key)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = c.Write(data); err != nil {
|
||||
globals.SugarLogger.Debugf("handleTcpMessages err [%v]", err)
|
||||
if printRemoteAddrIP, have := PrintIpAndAddr.GetPrintIpAndAddr(key); have {
|
||||
PrintIpAndAddr.DelPrintIpAndAddr(key)
|
||||
PrintAddrAndIp.DelPrintAddrAndIp(printRemoteAddrIP)
|
||||
PrintObject.DelPrintObj(key)
|
||||
}
|
||||
|
||||
} else {
|
||||
//等待回调
|
||||
dataStr := <-t.CallBackMap[key]
|
||||
if dataStr != "" {
|
||||
a, b := getCallbackMsgInfo(dataStr)
|
||||
t.changePrintMsg(dataStr, a, b)
|
||||
// 查询打印机是否扣费,未扣费就扣费,已经扣费不做处理
|
||||
have, err2 := dao.QueryOrderDeductionRecord(db, b, utils.Int64ToStr(a))
|
||||
if err2 == nil && !have {
|
||||
// 扣除打印机账号金额
|
||||
if err = dao.DeductionPrintBalance(db, b); err != nil {
|
||||
globals.SugarLogger.Debugf("扣除用户打印机金额错误 %s", err)
|
||||
} else {
|
||||
// 添加打印记录(支出记录)
|
||||
if err = dao.AddPrintRecord(db, &model.PrintBillRecord{
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
PrintNo: b,
|
||||
PayType: 2,
|
||||
PayMoney: 1, // 固定支出一分钱
|
||||
OrderId: utils.Int64ToStr(a),
|
||||
UserId: "",
|
||||
}); err != nil {
|
||||
globals.SugarLogger.Debugf("添加打印机订单支付记录错误 %s", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
globals.SugarLogger.Debugf("今天已经扣除过了! %v %d %s", err2, a, b)
|
||||
}
|
||||
// 回调重置打印机状态时间
|
||||
t.Clients[b].StatusTime = time.Now()
|
||||
//判断音频暂停?
|
||||
//收到打印成功回调后,如果消息中有音频,需要等待一下,等上一个音频播完
|
||||
//暂停时间就暂时取的sound标签内内容长度/2
|
||||
if sounds := regexpSoundSpan.FindStringSubmatch(printMsg.Content); len(sounds) > 0 {
|
||||
sound := sounds[1]
|
||||
lenTime := time.Duration(utf8.RuneCountInString(sound)) * time.Second
|
||||
time.Sleep(lenTime / 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
globals.SugarLogger.Debugf("doPrint timeout")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
Pool.AddJob(fn)
|
||||
return err
|
||||
}
|
||||
|
||||
// HandleCheckTcpHeart 检测心跳
|
||||
func HandleCheckTcpHeart(t *TcpClient, key string) {
|
||||
if t.TimeoutMap[key] == true {
|
||||
statusTime := t.getPrintStatusTime(key)
|
||||
if !utils.IsTimeZero(statusTime) {
|
||||
//1分钟内没心跳判断打印机掉线了
|
||||
if time.Now().Sub(statusTime) > time.Second*75 {
|
||||
globals.SugarLogger.Debugf("超过一分十秒没有心跳的打印机[%s],当前心跳时间: %s ,上一次心跳时间 : %s", key, utils.Time2TimeStr(time.Now()), utils.Time2TimeStr(statusTime))
|
||||
changePrinterStatus(key, printerStatusOffline)
|
||||
|
||||
// 链接出错,彻底删除换成
|
||||
if printRemoteAddrIP, have := PrintIpAndAddr.GetPrintIpAndAddr(key); have {
|
||||
PrintIpAndAddr.DelPrintIpAndAddr(key)
|
||||
PrintAddrAndIp.DelPrintAddrAndIp(printRemoteAddrIP)
|
||||
PrintObject.DelPrintObj(key)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
t.getClients(key).C.Close()
|
||||
close(t.MsgMap[key])
|
||||
close(t.CallBackMap[key])
|
||||
//t.delConn(key)
|
||||
t.clear(key)
|
||||
|
||||
// 链接出错,彻底删除换成
|
||||
if printRemoteAddrIP, have := PrintIpAndAddr.GetPrintIpAndAddr(key); have {
|
||||
PrintIpAndAddr.DelPrintIpAndAddr(key)
|
||||
PrintAddrAndIp.DelPrintAddrAndIp(printRemoteAddrIP)
|
||||
PrintObject.DelPrintObj(key)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user