一對一聊天(有bug)
阿新 • • 發佈:2019-03-22
錯誤 其中 用戶id msg pack tro conn pri 聊天
此處固定是發給clients["1"]客戶端消息,也就是發給自己。而且不是線程安全的!!!
package main import ( "github.com/gorilla/websocket" "net/http" "log" "fmt" ) type Message struct { Msg string // 消息內容 ToId string // 目標用戶的id FromId string // 發送消息的用戶的id } var clients = make(map[string] *websocket.Conn) //連接客戶端(在線的),其中map的鍵為用戶id var pushMsgs = make(chan Message, 1000) //要推送的消息 // 配置upgrader var upgrader = websocket.Upgrader{ // 允許跨域 CheckOrigin: func(r *http.Request) bool { return true }, } func main() { // 創建一個簡單的文件服務器 fs := http.FileServer(http.Dir("../public")) http.Handle("/", fs) // 配置websocket路由 http.HandleFunc("/ws", WsConns) // 收聽傳入的聊天信息 go ToMessage() // 在本地主機端口上啟動並記錄所有錯誤 log.Println("http server started on :8000") err := http.ListenAndServe(":8000", nil) if err != nil { log.Fatal("ListenAndServe error:", err) } } func WsConns(w http.ResponseWriter, r *http.Request) { //完成握手升級 ws, err := upgrader.Upgrade(w, r, nil) if err != nil { log.Fatal(err) } // 確保在函數返回時關閉連接 defer ws.Close() // 提示下機 defer fmt.Printf("——%v下機了——\n", ws.RemoteAddr()) // 註冊新客戶端 clients["1"] = ws //fmt.Println(clients["1"].) // 輸出ip fmt.Println("當前登錄用戶:", ws.RemoteAddr()) for { var msg Message err := ws.ReadJSON(&msg) if err != nil { log.Printf("error1: %v", err) // 若接收消息錯誤,則將該發送消息的用戶的websocket連接去掉 delete(clients, msg.FromId) } //將接收到的消息寫入消息channel pushMsgs <- msg } } func ToMessage() { for { // 從消息推送channel獲取消息 msg := <- pushMsgs // 發送給指定的客戶端 err := clients["1"].WriteJSON(msg) if err != nil { log.Printf("error2: %v", err) clients["1"].Close() delete(clients, "1") } } }
一對一聊天(有bug)