這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
最近寫了一個chrome的websocket extension, server端用的是Java的Netty架構, 後來發現golang 實現websocket 非常簡單,高效, 下面是例子, 簡單實現了使用者登入,廣播,相當於聊天室!
package mainimport ("code.google.com/p/go.net/websocket""html/template""log""net/http""os""strings""time")const (listenAddr = "localhost:9527" // server address)var (pwd, _ = os.Getwd()RootTemp = template.Must(template.ParseFiles(pwd + "/chat.html"))JSON = websocket.JSON // codec for JSONMessage = websocket.Message // codec for string, []byteActiveClients = make(map[ClientConn]string) // map containing clientsUser = make(map[string]string))// Initialize handlers and websocket handlersfunc init() {User["aaa"] = "aaa"User["bbb"] = "bbb"User["test"] = "test"User["test2"] = "test2"User["test3"] = "test3"}// Client connection consists of the websocket and the client iptype ClientConn struct {websocket *websocket.ConnclientIP string}// WebSocket server to handle chat between clientsfunc SockServer(ws *websocket.Conn) {var err errorvar clientMessage string// use []byte if websocket binary type is blob or arraybuffer// var clientMessage []byte// cleanup on server sidedefer func() {if err = ws.Close(); err != nil {log.Println("Websocket could not be closed", err.Error())}}()client := ws.Request().RemoteAddrlog.Println("Client connected:", client)sockCli := ClientConn{ws, client}ActiveClients[sockCli] = ""log.Println("Number of clients connected:", len(ActiveClients))// for loop so the websocket stays open otherwise// it'll close after one Receieve and Sendfor {if err = Message.Receive(ws, &clientMessage); err != nil {// If we cannot Read then the connection is closedlog.Println("Websocket Disconnected waiting", err.Error())// remove the ws client conn from our active clientsdelete(ActiveClients, sockCli)log.Println("Number of clients still connected:", len(ActiveClients))return}var msg_arr = strings.Split(clientMessage, "|")if msg_arr[0] == "login" && len(msg_arr) == 3 {name := msg_arr[1]pass := msg_arr[2]if pass == User[name] {ActiveClients[sockCli] = nameif err = Message.Send(ws, "login|"+name); err != nil {log.Println("Could not send message to ", client, err.Error())}} else {log.Println("login faild:", clientMessage)}} else if msg_arr[0] == "msg" {if ActiveClients[sockCli] != "" {clientMessage = "msg|" + time.Now().Format("2006-01-02 15:04:05") + " " + ActiveClients[sockCli] + " Said: " + msg_arr[1]for cs, na := range ActiveClients {if na != "" {if err = Message.Send(cs.websocket, clientMessage); err != nil {log.Println("Could not send message to ", cs.clientIP, err.Error())}}}}}}}// RootHandler renders the template for the root pagefunc RootHandler(w http.ResponseWriter, req *http.Request) {err := RootTemp.Execute(w, listenAddr)if err != nil {http.Error(w, err.Error(), http.StatusInternalServerError)}}func main() {http.HandleFunc("/", RootHandler)http.Handle("/socket", websocket.Handler(SockServer))err := http.ListenAndServe(listenAddr, nil)if err != nil {panic("ListenAndServe: " + err.Error())}}