This commit is contained in:
suyl
2021-07-29 14:49:22 +08:00
parent 2bc8c04bc6
commit 17dfe9e9df
3 changed files with 288 additions and 200 deletions

View File

@@ -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
}

View File

@@ -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 = "<br>" //换行
signCenter = "<center>" //居中
signLeft = "<left>" //居左
signRight = "<right>" //居右
signBig = "<b>" //字体放大
signHighBig = "<hb>" //字体纵向放大
signWideBig = "<wb>" //字体横向放大
signQrCenter = "<qrc>" //二维码居中
signQrLeft = "<qrl>" //二维码居左
signQrRight = "<qrr>" //二维码居右
signSound = "<sound>" //声音
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)
}
}
}

View File

@@ -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 = "<br>" //换行
signCenter = "<center>" //居中
signLeft = "<left>" //居左
signRight = "<right>" //居右
signBig = "<b>" //字体放大
signHighBig = "<hb>" //字体纵向放大
signWideBig = "<wb>" //字体横向放大
signQrCenter = "<qrc>" //二维码居中
signQrLeft = "<qrl>" //二维码居左
signQrRight = "<qrr>" //二维码居右
signSound = "<sound>" //声音
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),
}
}