1. 程式人生 > >採用beego框架構建 http伺服器

採用beego框架構建 http伺服器

     beego是一個使用 Go 的思維來快速構建並開發 Go 應用程式的開源http框架,作者是謝孟軍。它可以快速開發API、Web、後端服務等各種應用,功能支援RESTFul,MVC模型;含有智慧路由,內建強大模組,採用了 Go 原生的 http 包來處理請求;goroutine 的併發效率足以應付大流量的 Web 應用和 API 應用等等,可謂是簡單易用,十分強大。
     為了更好地熟悉beego框架,現在來構建一個簡單的http伺服器, PC客戶端通過http協議post請求通訊,並獲取伺服器返回的資訊。假設beego開發環境已安裝好,如果有疑問,可以參考之前寫的一篇blog:。

Go語言beego框架環境搭建
     我的beego工程名為ocean,GOPATH=E:\work\ocean。
     通訊流程
     這裡寫圖片描述

     新建專案
     通過“bee new 工程”命令,在GOPATH\src\ocean中建立瞭如下的檔案目錄:
     這裡寫圖片描述

     檔案結構:

ocean    
├── conf   
|   └── app.conf
├── controllers
|    └── default.go
├── main.go
├── models
├── routers   
|    └── router.go
├── static
│   ├── css
│   ├── img
│   └── js
├── tests
│   └── default_test.go
└── views └── index.tpl

     仔細看看,beego已經幫我們建立了諸如routers(路由),views(檢視),controller(控制器),models(資料模型),static(靜態檔案),tests(測試用例)等資料夾和相應的.go檔案了。Modoel,views和controller,依然是構建MVC模式的核心。
     程式入口
     設定beego框架啟動的監聽地址,埠號和程式名稱等初始化行為。

main.go程式碼:
package main

import (
    "github.com/astaxie/beego"
_ "ocean/routers" ) func main() { //beego全域性變數 beego.CopyRequestBody = true beego.AppName = "ocean" //設定http地址 beego.HttpAddr = "127.0.0.1" //設定http埠號 beego.HttpPort = 5170 //無引數,預設default run on HttpPort beego.Run() } //包含_ "ocean/routers",會執行router.go的init函式。

     智慧路由routers
     路由的主要功能是實現從請求地址到實現方法,通過實行路由註冊,我們把請求分發到指定的控制器來執行相應的邏輯。

router.go
func init() {
        //使用者就可以通過訪問url“/ocean”(使用者請求的地址) 去執行 OceanController 的邏輯
    beego.Router("/ocean", &controllers.OceanController{})
}

     控制器controllers
     根據路由分發的使用者請求, controller會進行業務邏輯處理並返回響應資訊。
基於beego的Controller設計,只需要匿名組合beego.Controller就可以實現beego controller了所有介面了。

type xxxController struct {
    beego.Controller
}

     由於用beego框架預設只重寫一個Get函式(開啟瀏覽器裡即可看到demo),而這次例子中pc客戶端提交的是post請求,所以要通過子struct的方法來重寫post函式,實現自己的邏輯。這裡可以先看看controller.go的原始碼:

Controller.go
// Post adds a request function to handle POST request.
func (c *Controller) Post() {
    http.Error(c.Ctx.ResponseWriter, "Method Not Allowed", 405)
}

     Post()
     如果使用者請求的HTTP Method是POST, 那麼就執行該函式,預設是405,使用者繼承的子struct中可以重新實現了該方法以處理Post請求。

controller程式碼:
default.go
type OceanController struct {
    beego.Controller
}

func (c *OceanController) Get() {
    c.Data["Website"] = "beego.me"
    c.Data["Email"] = "[email protected]"
    c.TplNames = "index.tpl"
}

//通過子struct的方法來重寫post函式,實現自己的邏輯。
func (c *OceanController) Post() {

    var req map[string]interface{}
    var res map[string]interface{}

    //請求資訊
    bufReq := c.Ctx.Input.RequestBody
    json.Unmarshal(bufReq, &req)
    //返回響應結果
    lenReq := len(bufReq)
    if lenReq > 1024 {
        beego.Info("req:", "\n"+string(bufReq[:64]), "...", string(bufReq[lenReq-64:]), "\n")
    } else {
        beego.Info("req:", "\n"+string(bufReq), "\n")
    }

    //模擬處理客戶端發來的請求訊息
    res = c.HandleReq(bufReq)

    bufRes, _ := json.MarshalIndent(res, "", "  ")
    lenRes := len(bufRes)
    if lenRes > 1024 {
        beego.Info("res:", "\n"+string(bufRes[:32]), "...", string(bufRes[lenRes-64:]), "\n")
    } else {
        beego.Info("res:", "\n"+string(bufRes), "\n")
    }

    c.Data["json"] = res
    c.ServeJson(false)
}

//-- 處理客戶端發來的請求訊息
//-- 引數:json資料,
func (c *OceanController) HandleReq(jsonData []byte) map[string]interface{} {

    var res map[string]interface{}

    json.Unmarshal(jsonData, &res)
    res["ver"] = 2
    res["cmd"] = "sys.pong"

    return res
}

     結果截圖
     請求
     這裡寫圖片描述
     這裡寫圖片描述
     響應
     這裡寫圖片描述
     這裡寫圖片描述