@ -9,19 +9,21 @@ import (
"sort"
"time"
)
type vistor struct {
conn * websocket . Conn
name string
id string
type vistor struct {
conn * websocket . Conn
name string
id string
avator string
to_id string
to_id string
}
type Message struct {
conn * websocket . Conn
c * gin . Context
content [ ] byte
type Message struct {
conn * websocket . Conn
c * gin . Context
content [ ] byte
messageType int
}
var clientList = make ( map [ string ] * vistor )
var kefuList = make ( map [ string ] [ ] * websocket . Conn )
var message = make ( chan * Message )
@ -31,21 +33,22 @@ type TypeMessage struct {
Data interface { } ` json:"data" `
}
type ClientMessage struct {
Name string ` json:"name" `
Avator string ` json:"avator" `
Id string ` json:"id" `
VisitorId string ` json:"visitor_id" `
Group string ` json:"group" `
Time string ` json:"time" `
ToId string ` json:"to_id" `
Content string ` json:"content" `
City string ` json:"city" `
Name string ` json:"name" `
Avator string ` json:"avator" `
Id string ` json:"id" `
VisitorId string ` json:"visitor_id" `
Group string ` json:"group" `
Time string ` json:"time" `
ToId string ` json:"to_id" `
Content string ` json:"content" `
City string ` json:"city" `
ClientIp string ` json:"client_ip" `
Refer string ` json:"refer" `
Refer string ` json:"refer" `
}
//定时检测客户端是否在线
func init ( ) {
upgrader = websocket . Upgrader {
upgrader = websocket . Upgrader {
ReadBufferSize : 1024 ,
WriteBufferSize : 1024 ,
}
@ -55,8 +58,8 @@ func init() {
//sendPingToClient()
}
func NewChatServer ( c * gin . Context ) {
conn , err := upgrader . Upgrade ( c . Writer , c . Request , nil )
func NewChatServer ( c * gin . Context ) {
conn , err := upgrader . Upgrade ( c . Writer , c . Request , nil )
if err != nil {
log . Print ( "upgrade:" , err )
return
@ -67,11 +70,11 @@ func NewChatServer(c *gin.Context){
var recevString string
messageType , receive , err := conn . ReadMessage ( )
if err != nil {
for uid , visitor := range clientList {
if visitor . conn == conn {
log . Println ( "删除用户" , uid )
delete ( clientList , uid )
models . UpdateVisitorStatus ( uid , 0 )
for uid , visitor := range clientList {
if visitor . conn == conn {
log . Println ( "删除用户" , uid )
delete ( clientList , uid )
models . UpdateVisitorStatus ( uid , 0 )
userInfo := make ( map [ string ] string )
userInfo [ "uid" ] = uid
userInfo [ "name" ] = visitor . name
@ -80,10 +83,10 @@ func NewChatServer(c *gin.Context){
Data : userInfo ,
}
str , _ := json . Marshal ( msg )
kefuConns := kefuList [ visitor . to_id ]
if kefuConns != nil {
for _ , kefuConn := range kefuConns {
kefuConn . WriteMessage ( websocket . TextMessage , str )
kefuConns := kefuList [ visitor . to_id ]
if kefuConns != nil {
for _ , kefuConn := range kefuConns {
kefuConn . WriteMessage ( websocket . TextMessage , str )
}
}
sendPingOnlineUsers ( )
@ -92,13 +95,13 @@ func NewChatServer(c *gin.Context){
log . Println ( err )
return
}
recevString = string ( receive )
recevString = string ( receive )
log . Println ( "客户端:" , recevString )
message <- & Message {
conn : conn ,
content : receive ,
c : c ,
messageType : messageType ,
message <- & Message {
conn : conn ,
content : receive ,
c : c ,
messageType : messageType ,
}
}
}
@ -108,17 +111,18 @@ func SendKefuOnline(clientMsg ClientMessage, conn *websocket.Conn) {
sendMsg := TypeMessage {
Type : "kfOnline" ,
Data : ClientMessage {
Name : clientMsg . Name ,
Avator : clientMsg . Avator ,
Id : clientMsg . Id ,
Group : clientMsg . Group ,
Time : time . Now ( ) . Format ( "2006-01-02 15:04:05" ) ,
Content : "客服上线" ,
Name : clientMsg . Name ,
Avator : clientMsg . Avator ,
Id : clientMsg . Id ,
Group : clientMsg . Group ,
Time : time . Now ( ) . Format ( "2006-01-02 15:04:05" ) ,
Content : "客服上线" ,
} ,
}
jsonStrByte , _ := json . Marshal ( sendMsg )
conn . WriteMessage ( websocket . TextMessage , jsonStrByte )
conn . WriteMessage ( websocket . TextMessage , jsonStrByte )
}
//发送通知
func SendNotice ( msg string , conn * websocket . Conn ) {
sendMsg := TypeMessage {
@ -126,7 +130,7 @@ func SendNotice(msg string, conn *websocket.Conn) {
Data : msg ,
}
jsonStrByte , _ := json . Marshal ( sendMsg )
conn . WriteMessage ( websocket . TextMessage , jsonStrByte )
conn . WriteMessage ( websocket . TextMessage , jsonStrByte )
}
//定时给客户端发送消息判断客户端是否在线
@ -138,28 +142,28 @@ func sendPingToClient() {
for {
str , _ := json . Marshal ( msg )
for uid , user := range clientList {
err := user . conn . WriteMessage ( websocket . TextMessage , str )
err := user . conn . WriteMessage ( websocket . TextMessage , str )
if err != nil {
delete ( clientList , uid )
models . UpdateVisitorStatus ( uid , 0 )
models . UpdateVisitorStatus ( uid , 0 )
}
}
for kefuId , kfConns := range kefuList {
var newkfConns = make ( [ ] * websocket . Conn , 0 )
for _ , kefuConn := range kfConns {
if ( kefuConn == nil ) {
var newkfConns = make ( [ ] * websocket . Conn , 0 )
for _ , kefuConn := range kfConns {
if kefuConn == nil {
continue
}
err := kefuConn . WriteMessage ( websocket . TextMessage , str )
err := kefuConn . WriteMessage ( websocket . TextMessage , str )
if err == nil {
newkfConns = append ( newkfConns , kefuConn )
newkfConns = append ( newkfConns , kefuConn )
}
}
if newkfConns == nil {
delete ( kefuList , kefuId )
} else {
kefuList [ kefuId ] = newkfConns
} else {
kefuList [ kefuId ] = newkfConns
}
}
time . Sleep ( 15 * time . Second )
@ -167,37 +171,39 @@ func sendPingToClient() {
} ( )
}
//定时给更新数据库状态
func sendPingUpdateStatus ( ) {
for {
visitors := models . FindVisitorsOnline ( )
for _ , visitor := range visitors {
_ , ok := clientList [ visitor . VisitorId ]
if ! ok {
models . UpdateVisitorStatus ( visitor . VisitorId , 0 )
visitors := models . FindVisitorsOnline ( )
for _ , visitor := range visitors {
_ , ok := clientList [ visitor . VisitorId ]
if ! ok {
models . UpdateVisitorStatus ( visitor . VisitorId , 0 )
}
}
time . Sleep ( 20 * time . Second )
}
}
//定时推送当前在线用户
func sendPingOnlineUsers ( ) {
var visitorIds [ ] string
for visitorId , _ := range clientList {
visitorIds = append ( visitorIds , visitorId )
visitorIds = append ( visitorIds , visitorId )
}
sort . Strings ( visitorIds )
for kefuId , kfConns := range kefuList {
result := make ( [ ] map [ string ] string , 0 )
for _ , visitorId := range visitorIds {
user := clientList [ visitorId ]
for _ , visitorId := range visitorIds {
user := clientList [ visitorId ]
userInfo := make ( map [ string ] string )
userInfo [ "uid" ] = user . id
userInfo [ "username" ] = user . name
userInfo [ "avator" ] = user . avator
if user . to_id == kefuId {
if user . to_id == kefuId {
result = append ( result , userInfo )
}
}
@ -206,31 +212,31 @@ func sendPingOnlineUsers() {
Data : result ,
}
str , _ := json . Marshal ( msg )
var newkfConns = make ( [ ] * websocket . Conn , 0 )
for _ , kefuConn := range kfConns {
err := kefuConn . WriteMessage ( websocket . TextMessage , str )
var newkfConns = make ( [ ] * websocket . Conn , 0 )
for _ , kefuConn := range kfConns {
err := kefuConn . WriteMessage ( websocket . TextMessage , str )
if err == nil {
newkfConns = append ( newkfConns , kefuConn )
newkfConns = append ( newkfConns , kefuConn )
}
}
if len ( newkfConns ) == 0 {
delete ( kefuList , kefuId )
} else {
kefuList [ kefuId ] = newkfConns
} else {
kefuList [ kefuId ] = newkfConns
}
}
}
//后端广播发送消息
func singleBroadcaster ( ) {
func singleBroadcaster ( ) {
for {
message := <- message
message := <- message
//log.Println("debug:",message)
var typeMsg TypeMessage
var clientMsg ClientMessage
json . Unmarshal ( message . content , & typeMsg )
conn := message . conn
conn := message . conn
if typeMsg . Type == nil || typeMsg . Data == nil {
continue
}
@ -240,22 +246,22 @@ func singleBroadcaster(){
//用户上线
case "userInit" :
json . Unmarshal ( msgData , & clientMsg )
vistorInfo := models . FindVisitorByVistorId ( clientMsg . VisitorId )
if vistorInfo . VisitorId == "" {
SendNotice ( "访客数据不存在" , conn )
vistorInfo := models . FindVisitorByVistorId ( clientMsg . VisitorId )
if vistorInfo . VisitorId == "" {
SendNotice ( "访客数据不存在" , conn )
continue
}
//用户id对应的连接
user := & vistor {
conn : conn ,
name : clientMsg . Name ,
user := & vistor {
conn : conn ,
name : clientMsg . Name ,
avator : clientMsg . Avator ,
id : clientMsg . VisitorId ,
to_id : clientMsg . ToId ,
id : clientMsg . VisitorId ,
to_id : clientMsg . ToId ,
}
clientList [ clientMsg . VisitorId ] = user
//插入数据表
models . UpdateVisitor ( clientMsg . VisitorId , 1 , clientMsg . ClientIp , message . c . ClientIP ( ) , clientMsg . Refer )
models . UpdateVisitor ( clientMsg . VisitorId , 1 , clientMsg . ClientIp , message . c . ClientIP ( ) , clientMsg . Refer )
//models.CreateVisitor(clientMsg.Name,clientMsg.Avator,message.c.ClientIP(),clientMsg.ToId,clientMsg.VisitorId,clientMsg.Refer,clientMsg.City,clientMsg.ClientIp)
userInfo := make ( map [ string ] string )
userInfo [ "uid" ] = user . id
@ -266,11 +272,11 @@ func singleBroadcaster(){
Data : userInfo ,
}
str , _ := json . Marshal ( msg )
kefuConns := kefuList [ user . to_id ]
if kefuConns != nil {
for k , kefuConn := range kefuConns {
log . Println ( k , "xxxxxxxx" )
kefuConn . WriteMessage ( websocket . TextMessage , str )
kefuConns := kefuList [ user . to_id ]
if kefuConns != nil {
for k , kefuConn := range kefuConns {
log . Println ( k , "xxxxxxxx" )
kefuConn . WriteMessage ( websocket . TextMessage , str )
}
}
//客户上线发微信通知
@ -280,10 +286,10 @@ func singleBroadcaster(){
case "kfOnline" :
json . Unmarshal ( msgData , & clientMsg )
//客服id对应的连接
var newKefuConns = [ ] * websocket . Conn { conn }
kefuConns := kefuList [ clientMsg . Id ]
if kefuConns != nil {
newKefuConns = append ( newKefuConns , kefuConns ... )
var newKefuConns = [ ] * websocket . Conn { conn }
kefuConns := kefuList [ clientMsg . Id ]
if kefuConns != nil {
newKefuConns = append ( newKefuConns , kefuConns ... )
}
log . Println ( newKefuConns )
kefuList [ clientMsg . Id ] = newKefuConns
@ -295,8 +301,8 @@ func singleBroadcaster(){
//客服接手
case "kfConnect" :
json . Unmarshal ( msgData , & clientMsg )
visitor , ok := clientList [ clientMsg . ToId ]
if visitor == nil || ! ok {
visitor , ok := clientList [ clientMsg . ToId ]
if visitor == nil || ! ok {
continue
}
SendKefuOnline ( clientMsg , visitor . conn )
@ -306,11 +312,8 @@ func singleBroadcaster(){
Type : "pong" ,
}
str , _ := json . Marshal ( msg )
conn . WriteMessage ( websocket . TextMessage , str )
conn . WriteMessage ( websocket . TextMessage , str )
}
}
}