/* * @Author: your name * @Date: 2021-10-21 22:36:25 * @LastEditTime: 2021-10-25 22:41:16 * @LastEditors: Please set LastEditors * @Description: In User Settings Edit * @FilePath: \webrtc_easy_signal\proto.go */ package main import ( "encoding/json" "log" "sync" ) type Request struct { Type int `json:"type"` Data map[string]interface{} `json:"data"` } const ( REQ_LOGIN = 1000 REQ_INROOM = 1001 REQ_LEAVEROOM = 1002 REQ_CREATEROOM = 1003 REQ_LISTROOM = 1004 REQ_SENDSDP = 1005 REQ_SENDCANDIDATE = 1006 RESP_LOGIN = 2000 RESP_INROOM = 2001 RESP_LEAVEROOM = 2002 RESP_CREATEROOM = 2003 RESP_LISTROOM = 2004 RESP_SENDSDP = 2005 RESP_SENDCANDIDATE = 2006 ) type Peer struct { Name string // 用户名 Ws *WsConnection // websocket连接 Room *Room // 当前处在哪个房间 } type Room struct { Name string // 房间名称 ws *WsConnection // websocket连接 Peers map[string]*Peer // 在房间里的节点 } var gmapRoom sync.Map var gmapUser sync.Map func get_room_online(name string) *Room{ room,ok := gmapRoom.Load(name) if ok{ return room.(*Room) } return nil } func get_peers_online(name string) *Peer { peer, ok := gmapUser.Load(name) if ok { return peer.(*Peer) } return nil } func get_interface_string(v interface{}) string { ret, ok := v.(string) if ok { return ret } return "" } func ProtoUnconnect(ws *WsConnection){ if nil == ws{ return } foundname := "" gmapUser.Range(func(key, value interface{}) bool { if value.(*Peer).Ws == ws{ foundname = value.(*Peer).Name if value.(*Peer).Room != nil{ delete(value.(*Peer).Room.Peers, foundname) peers_in_room := map[string]interface{}{} for _,v := range value.(*Peer).Room.Peers{ peers_in_room[v.Name] = true } for _,v := range value.(*Peer).Room.Peers{ v.Ws.SendPayload(RESP_LISTROOM,peers_in_room) } } } return true }) gmapUser.Delete(foundname) } func ProtoCallBack(ws *WsConnection, dat []byte) { if nil == ws { return } var payload Request e := json.Unmarshal(dat, &payload) if nil != e { log.Print(e.Error()) } log.Print(payload) switch payload.Type { case REQ_LOGIN: name := get_interface_string(payload.Data["name"]) if name != "" { if get_peers_online(name) != nil { log.Print("节点名重复") // todo 返回 ws.SendPayload(RESP_LOGIN,map[string]interface{}{ "status": -1, "data":"节点名重复", }) return } peer := new(Peer) peer.Name = name peer.Ws = ws gmapUser.Store(name, peer) ws.SendPayload(RESP_LOGIN,map[string]interface{}{ "status":0, "data":"success", }) } case REQ_INROOM: name := get_interface_string(payload.Data["name"]) room_name := get_interface_string(payload.Data["room_name"]) if (room_name != "") && (name != "") { // 不存在房间就创建房间 if _, ok := gmapRoom.Load(payload.Data["room_name"]); !ok { newroom := new(Room) newroom.Name = payload.Data["room_name"].(string) gmapRoom.Store(payload.Data["room_name"], newroom) // if peer, ok := gmapUser.Load(payload.Data["name"]); ok { newroom.Peers = make(map[string]*Peer) newroom.Peers[payload.Data["name"].(string)] = peer.(*Peer) } } else { // 将该用户添加进房间 peer := get_peers_online(name) peer.Room = get_room_online(room_name) peer.Room.Peers[name] = peer } room := get_room_online(room_name) peers_in_room := map[string]interface{}{} if nil != room{ for _,v := range room.Peers{ peers_in_room[v.Name] = true } for _,v := range room.Peers{ v.Ws.SendPayload(RESP_LISTROOM,peers_in_room) } } } break case REQ_CREATEROOM: break case REQ_LEAVEROOM: break case REQ_LISTROOM: // 显示room中其他成员 name := get_interface_string(payload.Data["name"]) peer := get_peers_online(name) if nil != peer{ } room_name := get_interface_string(payload.Data["room_name"]) room := get_room_online(room_name) peers_in_room := map[string]interface{}{} if nil != room{ for _,v := range room.Peers{ peers_in_room[v.Name] = true } } ws.SendPayload(RESP_LISTROOM,peers_in_room) break case REQ_SENDSDP: name := get_interface_string(payload.Data["name"]) peer_name := get_interface_string(payload.Data["remote_name"]) sdp := get_interface_string(payload.Data["sdp"]) if((name == "") ||(peer_name == "")){ return } peer_remote := get_peers_online(peer_name) if peer_remote != nil{ peer_remote.Ws.SendPayload(RESP_SENDSDP,map[string]interface{}{ "sdp":sdp, "remote_name":name, }) } break case REQ_SENDCANDIDATE: name := get_interface_string(payload.Data["name"]) peer_name := get_interface_string(payload.Data["remote_name"]) sdp := get_interface_string(payload.Data["candidate"]) peer_remote := get_peers_online(peer_name) if peer_remote != nil{ peer_remote.Ws.SendPayload(RESP_SENDCANDIDATE,map[string]interface{}{ "candidate":sdp, "remote_name":name, }) } break } }