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