直播商城原始碼,實現商城客服聊天,傳送文字、圖片的功能

zhibo系統開發發表於2022-03-14

直播商城原始碼,實現商城客服聊天,傳送文字、圖片的功能

1.實現的思路

由於之前寫python的時候接觸過websocket,但是當時是使用類似於廣播的機制的,沒有做過一對一的聊天.但是既然知道了廣播,那一對一也就不是什麼難事了

首先客戶端連線上來時,伺服器會例項化每個客戶端的連線,並且儲存這些連線,這時候只需要前端傳送訊息時,帶有聯絡人的id 這樣就可以根據id 找到聯絡人傳送訊息了


2.Demo 示例

下面是gin 實現的一個介面,使用 ws協議 連線該介面,然後就可以儲存一個ws的連線

// 把 http 升級為 ws
func Login(c *gin.Context)  {
tid := c.Query("tid")
userID , err := strconv.ParseInt(tid, 10, 64)
if err != nil {
c.JSON(http.StatusOK, gin.H{"code": 10, "arg-err": db.InvalidArgument})
return
}
Logger.Info(" ------ 請求頭 ------", c.Request.Header)
Logger.Info("ws 連線請求")
userInfo, err := db.FindUser(userID)
if err != nil {
Logger.Info("ws 連線失敗,找不到使用者資訊", err)
c.JSON(http.StatusOK, gin.H{"code": 10, "arg-err": db.InvalidArgument})
return
}
conn, err := Upgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
Logger.Error("http 協議升級為ws 協議失敗:", err)
return
}
uniqueID := utils.UUID()
wsClient := &Client{ID: utils.UUID(), Socket: conn, Send: make(chan []byte), UserInfo:userInfo, ConnID:uniqueID}
go wsClient.Read()
Manager.Register <- wsClient
Logger.Infof("ws 登陸成功 ip %v 使用者id %v", conn.RemoteAddr(), *wsClient.UserInfo.TID)
}


聊天功能demo

聊天功能主要是每個連線開了一個go 協程去檢查該連線是否有訊息,如果有訊息 則檢查它要發給哪個使用者,找到那個使用者的連線,發過去即可

func (c *Client) Read() {
defer func() {
Manager.Unregister <- c
c.Socket.Close()
}()
for {
Logger.Infof("使用者 %v 等待訊息中....", *c.UserInfo.TID)
_, message, err := c.Socket.ReadMessage()
if err != nil {
Logger.Error("讀取訊息失敗 ", err)
Manager.Unregister <- c
c.Socket.Close()
break
}
Logger.Info("====== ws 訊息 ====== ", string(message))
var content Message
err = json.Unmarshal(message, &content)
if err != nil {
Logger.Error("接收訊息失敗 ", err)
continue
}
if content.Content == "logout" {
Manager.Unregister <- c
c.Socket.Close()
break
}
if (content.Recipient == 0 || len(content.Content) == 0) && len(content.Image) < 0 {
Logger.Error("無效的訊息 ")
continue
}
// 儲存聊天記錄
unRead := db.MessageUnRead
msgType := content.Type
chat := &db.Chat{}
fromUser := c.UserInfo.TID
chat.FromUser = fromUser
chat.ToUser = &content.Recipient
chat.Content = &content.Content
chat.Image = &content.Image
chat.Status = &unRead
chat.Type = &msgType
db.SaveChat(chat)
now := time.Now()
nowTimeStamp := db.JSONTime{Time:now}
content.MsgID = *chat.TID
content.Timestamp = nowTimeStamp
content.Sender = *fromUser
// 轉發給另外一端
Logger.Infof("使用者 %v 發訊息 %v 給另外一個使用者 %v ", *fromUser, content.Content, content.Recipient)
Manager.ChatTo(content.Recipient, &content)
}
}
func (manager *ClientManager) ChatTo(userID int64, msg *Message) {
manager.Clients.Range(func(k, v interface{}) bool {
if v != nil {
conn := v.(*Client)
if *conn.UserInfo.TID == userID {
message, err := json.Marshal(msg)
if err != nil {
Logger.Error("聊天失敗")
return true
}
Logger.Info("傳送給 ", *conn.UserInfo.TID)
err = conn.Socket.WriteMessage(websocket.TextMessage, message)
if err != nil {
Logger.Error("訊息轉發失敗 ", err)
}
}
}
return true
})
}


關於離線訊息的處理

當聯絡人不線上時,我的處理方案是將聊天資料儲存下來標記該訊息未讀,提供一個介面查詢使用者未讀訊息,當下次使用者登陸時前端發http 請求未讀訊息即可


關於圖片傳送

這裡我的處理方案是,寫一個介面提供給前端上傳圖片上傳成功時返回圖片路徑,前端發來的聊天內容只有圖片的url,後續聊天圖片顯示通過url 請求圖片即可

以上就是直播商城原始碼,實現商城客服聊天,傳送文字、圖片的功能, 更多內容歡迎關注之後的文章


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69978258/viewspace-2870937/,如需轉載,請註明出處,否則將追究法律責任。

相關文章