package main import ( "encoding/json" "fmt" "github.com/beevik/guid" "github.com/gorilla/websocket" "net/http" "strings" "time" ) func signalHandler(w http.ResponseWriter, r *http.Request) { token := r.FormValue("token") if token == "" { fmt.Println("signalHandler Error : token is empty") } wsConn, upgradeErr := upgrader.Upgrade(w, r, w.Header()) if upgradeErr != nil { return } defer func() { if reco := recover(); reco != any(nil) { fmt.Printf("Signal Runtime error caught: %v", reco) } }() sessionGuid := guid.New().String() fastLinkService.NewSignalSession(token, sessionGuid, wsConn) wsConn.WriteMessage(websocket.TextMessage, []byte("0{\"sid\":\""+guid.New().String()+"\",\"upgrades\":[\"websocket\"],\"pingInterval\":25000,\"pingTimeout\":60000}")) wsConn.WriteMessage(websocket.TextMessage, []byte("40")) wsConn.WriteMessage(websocket.TextMessage, []byte("42[\"server-authenticated\",{\"uid\":\""+token+"\",\"authenticated\":true}]")) for { wsConn.SetReadDeadline(time.Now().In(TimeLocation).Add(time.Second * 60)) messageType, p, readError := wsConn.ReadMessage() if readError != nil { Logger.Println("Signal WebSocket异常断开," + wsConn.RemoteAddr().String() + ",异常信息:" + readError.Error()) signalSession := fastLinkService.GetSignalSession(token) fastLinkService.RemoveSignalSession(token, sessionGuid) if signalSession != nil { //推送UI提示 notifyOnlineUserChange(signalSession.RelateDeviceNo) } wsConn.Close() return } if messageType == websocket.CloseMessage { Logger.Println("Signal WebSocket断开," + wsConn.RemoteAddr().String()) signalSession := fastLinkService.GetSignalSession(token) fastLinkService.RemoveSignalSession(token, sessionGuid) if signalSession != nil { //推送UI提示 notifyOnlineUserChange(signalSession.RelateDeviceNo) } wsConn.Close() return } strData := string(p) //fmt.Printf("SIGNAL:" + strData + "\n") index := strings.Index(strData, "[") cmd := "" var items []interface{} if index != -1 { cmd = strData[0:index] json.Unmarshal([]byte(strData[index:]), &items) } else { cmd = strData } if len(cmd) > 1 && cmd[:2] == "42" { cmd = "42" } switch cmd { case "2": wsConn.WriteMessage(websocket.TextMessage, []byte("3")) case "42": if items[0] == "KeepAlive" { wsConn.WriteMessage(websocket.TextMessage, []byte("42[\"KeepAliveAck\",{}]")) } else if items[0] == "owt-message" { from := "" if _, ok := items[1].(map[string]interface{})["from"]; ok { from = items[1].(map[string]interface{})["from"].(string) } if from == "" { from = token } to := items[1].(map[string]interface{})["to"].(string) data := items[1].(map[string]interface{})["data"].(string) target := fastLinkService.GetSignalSession(to) if target != nil { target.WsConn.WriteMessage(websocket.TextMessage, makeOwtMessage(from, to, data)) } } } } } func makeOwtMessage(from string, to string, data string) []byte { var message []interface{} message = append(message, "owt-message") var m map[string]string m = make(map[string]string) m["from"] = from m["to"] = to m["data"] = data message = append(message, m) marshal, _ := json.Marshal(message) return append([]byte("42"), marshal...) }