使用 Go 語言和 HTML5 WebSocket 構建一個 Web 聊天室

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

這個應用示範如何使用 Google Go 語言和 HTML5 的 WebSocket 來實現一個簡單的基於 Web 的聊天程式。

是聊天應用的:

你可輸入 email 來加入聊天室,我們將從 Gravatar 上擷取對應的使用者名稱和頭像,當你正在聊天時,你能在介面右側看到聊天室其他人的姓名和頭像。你可以輸入資訊來跟他們聊天。

現在,讓我們來看看如何?這麼一個程式。

伺服器端

首先我們需要一個名為 ActiveRoom 聊天室引擎作為整個應用的核心。該引擎將在下面的代碼中定義,當程式主函數啟動時將會初始化一個聊天室引擎執行個體並作為一個全域變數。

正在啟動並執行執行個體用於維護所有 websocket 串連並處理收到的訊息。一旦通過廣播渠道接收到一個新的訊息,它會將該訊息發送到所有串連發送渠道。

Message 是伺服器和用戶端資料互動的基礎資料型別 (Elementary Data Type),在這裡我們定義了兩個訊息類型,一個是簡訊,另外一個是即時的使用者線上狀態。

type ActiveRoom struct {     OnlineUsers map[string]*OnlineUser     Broadcast   chan Message     CloseSign   chan bool}type Message struct {     MType       string     TextMessage TextMessage     UserStatus  UserStatus}func (this *ActiveRoom) run() {     for {          select {          case b := <-this.Broadcast:               for _, online := range this.OnlineUsers {                    online.Send <- b               }          case c := <-this.CloseSign:               if c == true {                    close(this.Broadcast)                    close(this.CloseSign)                    return               }          }     }}


OnlineUser 類代表一個成功串連到聊天室的使用者,它維護著 ActiveRoom 執行個體的指標、伺服器和用戶端之間的 websocket 串連,同時包括正在聊天的使用者和 Go 的通訊渠道。

OnlineUser 定義了兩個指標方法

PushToClient:
從發送渠道讀取訊息然後將這些訊息通過 websocket 推送給用戶端。

PullFromClient:
從用戶端讀取訊息並發送到正在啟動並執行 ActiveRoom 執行個體。

這兩個方法使用 "for" 語句來等待新的訊息,除非 websocket 串連中斷。

type OnlineUser struct {     InRoom     *ActiveRoom     Connection *websocket.Conn     UserInfo   *User     Send       chan Message}func (this *OnlineUser) PullFromClient() {     for {          var content string          err := websocket.Message.Receive(this.Connection, &content)          if err != nil {               return          }          m := Message{               MType: TEXT_MTYPE,               TextMessage: TextMessage{                    UserInfo: this.UserInfo,                    Time:     humanCreatedAt(),                    Content:  content,               },          }          this.InRoom.Broadcast <- m     }}func (this *OnlineUser) PushToClient() {     for b := range this.Send {          err := websocket.JSON.Send(this.Connection, b)          if err != nil {               break          }     }}


下面我們來看看程式流程,BuildConnection 函數在 main 函數中被註冊為 websocket 串連的處理器:

http.Handle("/chat", websocket.Handler(wscon.BuildConnection))


當有一個 websocket 串連請求,該函數將做一些初始化工作用於處理新的串連:

func BuildConnection(ws *websocket.Conn) {     email := ws.Request().URL.Query().Get("email")     onlineUser := &OnlineUser{          InRoom:     runningActiveRoom,          Connection: ws,          Send:       make(chan Message, 256),          UserInfo: &User{               Email:    email,               Name:     strings.Split(email, "@")[0],               Gravatar: libs.UrlSize(email, 20),          },     }     runningActiveRoom.OnlineUsers[email] = onlineUser     m := Message{          MType: STATUS_MTYPE,          UserStatus: UserStatus{               Users: runningActiveRoom.GetOnlineUsers(),          },     }     runningActiveRoom.Broadcast <- m     go onlineUser.PushToClient()     onlineUser.PullFromClient()     onlineUser.killUserResource()}


用戶端

最後一部分是用戶端的實現,這是採用 JavaScript 實現的。它開啟了一個新的 websocket 串連到聊天伺服器,並註冊回呼函數用於處理來自伺服器端的訊息。你會發現當串連收到新的訊息時,conn.onmessage 將被調用。現在你只需將接收到的訊息交給對應的 JavaScript 函數去處理:

if (window["WebSocket"]) {    conn = new WebSocket("ws://{{.WebSocketHost}}/chat?email={{.Email}}");    conn.onopen = function() {};    conn.onmessage = function(evt) {         var data = JSON.parse(evt.data);         switch(data.MType) {              case "text_mtype":                   addMessage(data.TextMessage)                   break;              case "status_mtype":                   updateUsers(data.UserStatus)                   break;              default:         }    };    conn.onerror = function() {           errorMessage("<strong> An error just occured.<strong>")    };    conn.onclose = function() {           errorMessage("<strong>Connection closed.<strong>")    };} else {    errorMessage("Your browser does not support WebSockets.");}


如果你對這個應用高度興趣,你可以從這裡擷取整個應用的源碼:gochatting.

英文原文,OSCHINA原創翻譯

轉自:http://www.oschina.net/question/12_63247?from=20120805
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.