[Golang]简单的聊天室实现

abv123456789 · · 4550 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。


最近写了一个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. }  

有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:abv123456789

查看原文:[Golang]简单的聊天室实现

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4550 次点击  
加入收藏 微博
被以下专栏收入,发现更多相似内容
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传