[Golang]简单的聊天室实现


最近写了一个chrome的websocket extension, server端用的是Java的Netty框架, 后来发现golang 实现websocket 非常简单,高效, 下面是例子, 简单实现了用户登录,广播,相当于聊天室!


  1. package main  
  2.   
  3. import (  
  4.     "code.google.com/p/go.net/websocket"  
  5.     "html/template"  
  6.     "log"  
  7.     "net/http"  
  8.     "os"  
  9.     "strings"  
  10.     "time"  
  11. )  
  12.   
  13. const (  
  14.     listenAddr = "localhost:9527" // server address  
  15. )  
  16.   
  17. var (  
  18.     pwd, _        = os.Getwd()  
  19.     RootTemp      = template.Must(template.ParseFiles(pwd + "/chat.html"))  
  20.     JSON          = websocket.JSON              // codec for JSON  
  21.     Message       = websocket.Message           // codec for string, []byte  
  22.     ActiveClients = make(map[ClientConn]string) // map containing clients  
  23.     User          = make(map[string]string)  
  24. )  
  25.   
  26. // Initialize handlers and websocket handlers  
  27. func init() {  
  28.     User["aaa"] = "aaa"  
  29.     User["bbb"] = "bbb"  
  30.     User["test"] = "test"  
  31.     User["test2"] = "test2"  
  32.     User["test3"] = "test3"  
  33. }  
  34.   
  35. // Client connection consists of the websocket and the client ip  
  36. type ClientConn struct {  
  37.     websocket *websocket.Conn  
  38.     clientIP  string  
  39. }  
  40.   
  41. // WebSocket server to handle chat between clients  
  42. func SockServer(ws *websocket.Conn) {  
  43.     var err error  
  44.     var clientMessage string  
  45.     // use []byte if websocket binary type is blob or arraybuffer  
  46.     // var clientMessage []byte  
  47.   
  48.     // cleanup on server side  
  49.     defer func() {  
  50.         if err = ws.Close(); err != nil {  
  51.             log.Println("Websocket could not be closed", err.Error())  
  52.         }  
  53.     }()  
  54.   
  55.     client := ws.Request().RemoteAddr  
  56.     log.Println("Client connected:", client)  
  57.     sockCli := ClientConn{ws, client}  
  58.     ActiveClients[sockCli] = ""  
  59.     log.Println("Number of clients connected:", len(ActiveClients))  
  60.   
  61.     // for loop so the websocket stays open otherwise  
  62.     // it'll close after one Receieve and Send  
  63.     for {  
  64.         if err = Message.Receive(ws, &clientMessage); err != nil {  
  65.             // If we cannot Read then the connection is closed  
  66.             log.Println("Websocket Disconnected waiting", err.Error())  
  67.             // remove the ws client conn from our active clients  
  68.             delete(ActiveClients, sockCli)  
  69.             log.Println("Number of clients still connected:", len(ActiveClients))  
  70.             return  
  71.         }  
  72.   
  73.         var msg_arr = strings.Split(clientMessage, "|")  
  74.         if msg_arr[0] == "login" && len(msg_arr) == 3 {  
  75.             name := msg_arr[1]  
  76.             pass := msg_arr[2]  
  77.   
  78.             if pass == User[name] {  
  79.                 ActiveClients[sockCli] = name  
  80.   
  81.                 if err = Message.Send(ws, "login|"+name); err != nil {  
  82.                     log.Println("Could not send message to ", client, err.Error())  
  83.                 }  
  84.             } else {  
  85.                 log.Println("login faild:", clientMessage)  
  86.             }  
  87.   
  88.         } else if msg_arr[0] == "msg" {  
  89.             if ActiveClients[sockCli] != "" {  
  90.                 clientMessage = "msg|" + time.Now().Format("2006-01-02 15:04:05") + " " + ActiveClients[sockCli] + " Said: " + msg_arr[1]  
  91.                 for cs, na := range ActiveClients {  
  92.                     if na != "" {  
  93.                         if err = Message.Send(cs.websocket, clientMessage); err != nil {  
  94.                             log.Println("Could not send message to ", cs.clientIP, err.Error())  
  95.                         }  
  96.                     }  
  97.                 }  
  98.             }  
  99.         }  
  100.     }  
  101. }  
  102.   
  103. // RootHandler renders the template for the root page  
  104. func RootHandler(w http.ResponseWriter, req *http.Request) {  
  105.     err := RootTemp.Execute(w, listenAddr)  
  106.     if err != nil {  
  107.         http.Error(w, err.Error(), http.StatusInternalServerError)  
  108.     }  
  109. }  
  110.   
  111. func main() {  
  112.     http.HandleFunc("/", RootHandler)  
  113.     http.Handle("/socket", websocket.Handler(SockServer))  
  114.     err := http.ListenAndServe(listenAddr, nil)  
  115.     if err != nil {  
  116.         panic("ListenAndServe: " + err.Error())  
  117.     }  
  118. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值