package controller import ( "encoding/json" "github.com/gin-gonic/gin" "github.com/taoshihan1991/imaptool/tmpl" "github.com/taoshihan1991/imaptool/tools" "golang.org/x/net/websocket" "log" "net/http" "time" ) //聊天主界面 func ActionChatMain(w http.ResponseWriter, r *http.Request) { render := tmpl.NewRender(w) render.Display("chat_main", nil) } //聊天客户端界面 func ActionChatPage(w http.ResponseWriter, r *http.Request){ render := tmpl.NewRender(w) render.Display("chat_page", nil) } //咨询界面 func PageChat(c *gin.Context){ html := tools.FileGetContent("html/chat_page.html") c.Header("Content-Type", "text/html; charset=utf-8") c.String(200, html) } //获取在线用户 func ChatUsers(w http.ResponseWriter, r *http.Request) { w.Header().Set("content-type", "text/json;charset=utf-8;") result := make([]map[string]string, 0) for uid, _ := range clientList { userInfo := make(map[string]string) userInfo["uid"] = uid userInfo["username"]=clientNameList[uid] result = append(result, userInfo) } msg, _ := json.Marshal(tools.JsonListResult{ JsonResult: tools.JsonResult{Code: 200, Msg: "获取成功"}, Result: result, }) w.Write(msg) } type NoticeMessage struct { Type interface{} `json:"type"` Data interface{} `json:"data"` } type TypeMessage struct { Type interface{} `json:"type"` Data interface{} `json:"data"` } type KfMessage struct { Kf_name string `json:"kf_name"` Avatar string `json:"avatar"` Kf_id string `json:"kf_id"` Kf_group string `json:"kf_group"` Time string `json:"time"` Guest_id string `json:"guest_id"` Content string `json:"content"` } type UserMessage struct { From_avatar string `json:"from_avatar"` From_id string `json:"from_id"` From_name string `json:"from_name"` To_id string `json:"to_id"` To_name string `json:"to_name"` Time string `json:"time"` Content string `json:"content"` } //定时检测客户端是否在线 func init() { sendPingToClient() } //兼容之前的聊天服务 func ChatServer(w *websocket.Conn) { var error error for { //接受消息 var receive string if error = websocket.Message.Receive(w, &receive); error != nil { log.Println("接受消息失败", error) break } log.Println("客户端:", receive) var typeMsg TypeMessage var kfMsg KfMessage var userMsg UserMessage json.Unmarshal([]byte(receive), &typeMsg) if typeMsg.Type==nil||typeMsg.Data==nil{ break } msgType:=typeMsg.Type.(string) msgData, _ :=json.Marshal(typeMsg.Data) switch msgType { //获取当前在线的所有用户 case "getOnlineUsers": getOnlineUser(w) //用户上线 case "userInit": json.Unmarshal(msgData,&userMsg) //用户id对应的连接 clientList[userMsg.From_id] = w clientNameList[userMsg.From_id]=userMsg.From_name SendUserAllNotice() //客服上线 case "kfOnline": json.Unmarshal(msgData,&kfMsg) //客服id对应的连接 kefuList[kfMsg.Kf_id] = w //发送给客户 if len(clientList)==0{ break } for _, conn := range clientList { SendKefuOnline(kfMsg,conn) } //发送给客服通知 //SendOnekfuAllNotice(w) //客服接手 case "kfConnect": json.Unmarshal(msgData,&kfMsg) kefuList[kfMsg.Kf_id] = w SendKefuOnline(kfMsg,clientList[kfMsg.Guest_id]) case "kfChatMessage": json.Unmarshal(msgData,&kfMsg) conn:=clientList[kfMsg.Guest_id] if kfMsg.Guest_id=="" ||conn==nil{ return } msg:=NoticeMessage{ Type: "kfChatMessage", Data:KfMessage{ Kf_name: kfMsg.Kf_name, Avatar: kfMsg.Avatar, Kf_id: kfMsg.Kf_id, Time: time.Now().Format("2006-01-02 15:04:05"), Guest_id: kfMsg.Guest_id, Content: kfMsg.Content, }, } str,_:=json.Marshal(msg);sendStr:=string(str) websocket.Message.Send(conn,sendStr) case "chatMessage": json.Unmarshal(msgData,&userMsg) conn:=kefuList[userMsg.To_id] msg:=NoticeMessage{ Type: "chatMessage", Data:UserMessage{ From_avatar: userMsg.From_avatar, From_id: userMsg.From_id, From_name: userMsg.From_name, To_id: userMsg.To_id, To_name: userMsg.To_name, Content: userMsg.Content, Time: time.Now().Format("2006-01-02 15:04:05"), }, } str,_:=json.Marshal(msg);sendStr:=string(str) websocket.Message.Send(conn,sendStr) } } } //发送给所有客服客户上线 func SendUserAllNotice(){ if len(kefuList)!=0{ //发送给客服通知 for _, conn := range kefuList { msg:=NoticeMessage{ Type: "notice", } str,_:=json.Marshal(msg);sendStr:=string(str) websocket.Message.Send(conn,sendStr) } } } //发送给客户客服上线 func SendKefuOnline(kfMsg KfMessage,conn *websocket.Conn){ sendMsg := TypeMessage{ Type: "kfOnline", Data: KfMessage{ Kf_name: kfMsg.Kf_name, Avatar: kfMsg.Avatar, Kf_id: kfMsg.Kf_id, Kf_group: kfMsg.Kf_group, Time: time.Now().Format("2006-01-02 15:04:05"), Content: "客服上线", }, } jsonStrByte, _ := json.Marshal(sendMsg) websocket.Message.Send(conn, string(jsonStrByte)) } //发送给所有客服客户上线 func SendOnekfuAllNotice(conn *websocket.Conn){ result := make([]map[string]string, 0) for uid, _ := range clientList { userInfo := make(map[string]string) userInfo["uid"] = uid userInfo["username"]=clientNameList[uid] result = append(result, userInfo) } msg:=NoticeMessage{ Type: "notice", Data:result, } str,_:=json.Marshal(msg);sendStr:=string(str) websocket.Message.Send(conn,sendStr) } //获取当前的在线用户 func getOnlineUser(w *websocket.Conn){ result := make([]map[string]string, 0) for uid, _ := range clientList { userInfo := make(map[string]string) userInfo["uid"] = uid userInfo["username"]=clientNameList[uid] result = append(result, userInfo) } msg:=NoticeMessage{ Type: "getOnlineUsers", Data:result, } str,_:=json.Marshal(msg);sendStr:=string(str) websocket.Message.Send(w,sendStr) } //定时给客户端发送消息判断客户端是否在线 func sendPingToClient(){ msg:=NoticeMessage{ Type: "ping", } go func() { for{ log.Println("check online users...") str,_:=json.Marshal(msg);sendStr:=string(str) for uid, conn := range clientList { err:=websocket.Message.Send(conn,sendStr) if err!=nil{ delete(clientList,uid) SendUserAllNotice() } } time.Sleep(10*time.Second) } }() } var clientList = make(map[string]*websocket.Conn) var clientNameList = make(map[string]string) var kefuList = make(map[string]*websocket.Conn)