之前使用pusher.com提供的商业服务器,但在我的站速度慢,消息传递有丢失情况,所以自行构架
主要实现通知功能:
1. 根据每个page的 session_id来区分连接,数组方式存放,应对当一个session打开了多个page的情形
2.json格式进行通讯,数据中指定要通知的session,该session下的所有page将收到通知,session_id至少做md5处理
package main import ( "flag" "fmt" "net/http" "code.google.com/p/go.net/websocket") var port *int = flag.Int("p", 443, "Port to listen.") //创建全局map,可以为sess_id,value为ws数组(指针) var conns = make(map[string][]*websocket.Conn) //type Msg struct { // Sender string // Receiver string // Command string // Data map(string)interface{} //} // jsonServer echoes back json string sent from client using websocket.JSON. func server(ws *websocket.Conn) { defer ws.Close() req := ws.Request() req.ParseForm() //client := req.FormValue("client") sess_id := req.FormValue("sess_id"); //ver := req.FormValue("ver") //其它地方发起一个通知请求,按要求进行处理 //登记连接 if client, ok := conns[sess_id]; !ok { conns[sess_id] = []*websocket.Conn{ws} } else { conns[sess_id] = append(client, ws) } //ws_list, _ := conns[sess_id] //ws_list[1] = ws //defer delete(conns, sess_id) for { // Receive receives a text message serialized T as JSON. var msg map[string]interface{} err := websocket.JSON.Receive(ws, &msg) if err != nil { fmt.Println(err) break } fmt.Printf("recv:%#v\n", msg) // Send send a text message serialized T as JSON. var receiver string for k,v := range msg { if k == "Receiver" { receiver = v.(string) } } if receiver_ws_list, ok := conns[receiver]; ok { //fmt.Printf("sess client count: %#i\n", len(receiver_ws_list)) for _, receiver_ws := range receiver_ws_list { err = websocket.JSON.Send(receiver_ws, msg) if (err != nil) { fmt.Println("failed to send!") } } fmt.Println("sended!") } if err != nil { fmt.Println(err) break } fmt.Printf("send:%#v\n", msg) } my_ws_list, _ := conns[sess_id] for i, my_ws := range my_ws_list { if my_ws == ws { conns[sess_id] = append(my_ws_list[:i], my_ws_list[i+1:]...) fmt.Printf("a client removed\n") } } //remove ws form slice fmt.Printf("a client closed\n") } func main() { flag.Parse() http.Handle("/", websocket.Handler(server)) fmt.Printf("http://localhost:%d/\n", *port) err := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil) if err != nil { panic("ListenANdServe: " + err.Error()) } }
有疑问加站长微信联系(非本文作者)