beego 的 http server…

Author 逆雪寒 2015.12.02

原文地址 https://github.com/nixuehan/beego_you_know/blob/master/kernel.md

在工作中有用到golang,后来遇到了beego 重构了一下我的应用。感觉棒棒的~ 应用强壮了不少。所以我打算以最新的stable v1.5.0 来剖析下beego的源代码,因为知其然知其所以然.我们才能更好的使用beego ,同时提高我们的golang能力 。加我的群吧 一起学习 群号:511634754

* beego 的源代码里,为了让大家顺畅阅读更好理解。我会删掉那些本节我没分析到的代码。

这 节我们先从 beego 的 http server 说起。我们会抽丝剥茧,让一个最简单的的 “beego” 跑起来。最基础最核心其实就两样东西. http.Server 和 Handler 他们的关系~就类似 麦当劳 和 麦当劳里的服务员妹子。 先有了麦当劳..然后 你给钱妹子。。妹子给你冰淇淋。。也就 请求和输出..

这段是官网贴的启动beego的代码。 那我们就从 Run 这个函数开始

  1. package main
  2. import "github.com/astaxie/beego"
  3. func main() {
  4. beego.Run()
  5. }
beego.go文件
  1. // Run 函数 有一个可变参数 ...string 相当于 []string{} 这个不懂..那就别继续往下看了~先复习golang基础
  2. // 此参数是告知 http server 要绑定的 host 和 port 。 例如: 127.0.0.1:9413
  3. func Run(params ...string) {
  4. if len(params) > 0 && params[0] != "" {
  5. // -_- 看看人家是怎么把 地址和端口拆到两个变量里去的...
  6. // HttpAddr 和 HttpPort 这两个变量是在 config.go 里定义的 大写字母开头哦~ 是全局变量
  7. // 记录了http server 要绑定的地址和 端口号,方便在其他模块进行调用
  8. strs := strings.Split(params[0], ":")
  9. if len(strs) > 0 && strs[0] != "" {
  10. HttpAddr = strs[0]
  11. }
  12. if len(strs) > 1 && strs[1] != "" {
  13. HttpPort, _ = strconv.Atoi(strs[1])
  14. }
  15. }
  16. //要绑定的地址和端口都得到了之后。正式启动。 调用BeeApp 里面的方法 Run
  17. BeeApp.Run()
  18. }

BeeApp 这个结构很重要。很多底层的都封装在这个结构里。我们看下 它的 Run 是啥东西。 BeeApp 是一个指向 App结构的变量。 在 config.go 文件里定义

config.go文件
  1. var (
  2. BeeApp *App

同时在 init 函数里 里进行初始化

  1. // import的时候其实是执行了该包里面的init函数。。应该懂吧
  2. //执行了 NewApp() 函数~ 那 NewApp 函数执行了啥呢。。我们一层一层的脱了她的衣服....接着看
  3. func init() {
  4. BeeApp = NewApp()

NewApp 函数定义在 app.go 文件里。 看代码…

app.go文件
  1. type App struct {
  2. Server *http.Server // 这个就是 麦当劳..
  3. Handlers *ControllerRegistor //这个就是麦当劳里面的服务员妹子。具体代码请看后面
  4. }
  5. func NewApp() *App {
  6. cr := NewControllerRegister() //new 一个 Handlers,方便用来处理 http服务 的输入和输出
  7. //初始化了 App结构。http.Server 这个就是golang自带的http server了~ 太好理解了。这样
  8. //app.Server 就是 等于 http.Server了~ 如果我们不用 beego 的时候。 写个http server
  9. //是不是直接调用 http.Server.ListenAndServe()就很容易实现一个 类似nginx 的基础http 服务器
  10. //那可能有的人说 http.ListenAndServe() 这样就可以啦。嗯 不过看下源代码就知道
  11. //http.ListenAndServe 其实 也是调用更底层的 http.Server.ListenAndServe 。 beego
  12. //为了灵活性所以用更底层的 http.Server.ListenAndServe
  13. app := &App{Handlers: cr,Server: &http.Server{}}
  14. return app
  15. }
  16. func (app *App) Run() {
  17. endRunning := make(chan bool, 1)
  18. go func() {
  19. // 组装好绑定地址和端口
  20. addr := fmt.Sprintf("%s:%d", HttpAddr, HttpPort)
  21. //前面我们说了 app.Server 其实就是 http.Server。 那么我们看下官网手册 http.Server 这个结构里有啥
  22. //type Server struct {
  23. //Addr string // TCP address to listen on, ":http" if empty
  24. //Handler Handler // handler to invoke, http.DefaultServeMux if nil
  25. //ReadTimeout time.Duration // maximum duration before timing out read of the request
  26. //WriteTimeout time.Duration // maximum duration before timing out write of the response
  27. //MaxHeaderBytes int // maximum size of request headers, DefaultMaxHeaderBytes if 0
  28. //TLSConfig *tls.Config // optional TLS config, used by ListenAndServeTLS
  29. // 我们这里可以只关注。两个变量 Addr 和 Handler
  30. // Addr 就是我们要绑定的地址和端口
  31. // Handler 就是我们的处理器, GET POST PUT 等请求就是需要他接收和输出..
  32. // 这么理解吧 http.Server 这个结构就像是麦当劳.. 而 Handler 就是服务员小妹妹,
  33. // 她负责收钱 和给你冰淇淋
  34. //确定要绑定ip和端口
  35. app.Server.Addr = addr
  36. //确定这个http容器里负责处理 输入和输出的方法.. 就是那个 麦当劳服务员小妹妹,你给她钱。她给你...
  37. app.Server.Handler = app.Handlers
  38. //下面就是标准的启动一个 golang http server 的流程了...
  39. ln, err := net.Listen("tcp4", app.Server.Addr)
  40. if err != nil {
  41. endRunning <- true
  42. return
  43. }
  44. err = app.Server.Serve(ln)
  45. if err != nil {
  46. endRunning <- true
  47. return
  48. }
  49. }()
  50. //channel 默认是阻塞。 利用这点。阻塞宿主程序。 否则~~ 宿主都退出了 而 go func 里面的程序~自然也就不存在了
  51. <-endRunning
  52. }

上面是创建了 http 服务容器。接下来就是 接待输入和输出的自定义方法。beego是怎么设计的呢。只有一个目的就是实现ServeHTTP 这个方法。只有实现了这个方法,那么才符合 app.Server.Handler = app.Handlers。我们看下官网手册 http 这节对于Handler的定义。

  1. type Handler interface {
  2. ServeHTTP(ResponseWriter, *Request)
  3. }

其实就是一个接口。里面只有一个方法.. 你懂了吗? interface 你可以理解为Handler发动机设计图. 无论是歼20还是歼16,只要按照图纸做出来的发动机,当然里面的细节可以根据具体的战斗机需要进行调整(实现了 ServeHTTP这个方法)..我们都可以说 这款战机的发动机是 Handler发动机 -_-! 讲了好多废话..

router.go
  1. //beego 从命名中可以get到~~ 这个是控制器注册器
  2. type ControllerRegistor struct {
  3. }
  4. //模仿 new go 例牌
  5. func NewControllerRegister() *ControllerRegistor {
  6. return &ControllerRegistor{}
  7. }
  8. //就是这个东西。http容器里的输入输出我们如何把玩?就看你怎么实现 ServeHTTP 这个方法了。
  9. func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
  10. //在这里。你可以自由的发挥了。比如 写你自己的 路由算法 等等等...
  11. //这段是我自己加的。为了能输出清晰点。。。
  12. rw.Header().Set("Content-Type", "text/plain; charset=utf-8") // normal header
  13. rw.WriteHeader(http.StatusOK)
  14. io.WriteString(rw,"加我的群 golang 一起学习 群号:511634754")

go框架的更多相关文章

  1. 避免重复造轮子的UI自动化测试框架开发

    一懒起来就好久没更新文章了,其实懒也还是因为忙,今年上半年的加班赶上了去年一年的加班,加班不息啊,好了吐槽完就写写一直打算继续的自动化开发 目前各种UI测试框架层出不穷,但是万变不离其宗,驱动PC浏览 ...

  2. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  3. 旺财速啃H5框架之Bootstrap(五)

    在上一篇<<旺财速啃H5框架之Bootstrap(四)>>做了基本的框架,<<旺财速啃H5框架之Bootstrap(二)>>篇里也大体认识了bootst ...

  4. Angular企业级开发(5)-项目框架搭建

    1.AngularJS Seed项目目录结构 AngularJS官方网站提供了一个angular-phonecat项目,另外一个就是Angular-Seed项目.所以大多数团队会基于Angular-S ...

  5. Scrapy框架爬虫初探——中关村在线手机参数数据爬取

    关于Scrapy如何安装部署的文章已经相当多了,但是网上实战的例子还不是很多,近来正好在学习该爬虫框架,就简单写了个Spider Demo来实践.作为硬件数码控,我选择了经常光顾的中关村在线的手机页面 ...

  6. 制作类似ThinkPHP框架中的PATHINFO模式功能

    一.PATHINFO功能简述 搞PHP的都知道ThinkPHP是一个免费开源的轻量级PHP框架,虽说轻量但它的功能却很强大.这也是我接触学习的第一个框架.TP框架中的URL默认模式即是PathInfo ...

  7. 旺财速啃H5框架之Bootstrap(四)

    上一篇<<旺财速啃H5框架之Bootstrap(三)>>已经把导航做了,接下来搭建内容框架.... 对于不规整的网页,要做成自适应就有点玩大了.... 例如下面这种版式的页面. ...

  8. 一起学 Java(三) 集合框架、数据结构、泛型

    一.Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构.所有的集合框架都包含如下内容: 接口:是代表集合的抽象数据类型.接口允许集合独立操纵其代表的细节.在面向对象的语言,接口通常形成一个 ...

  9. Hibernatel框架关联映射

    Hibernatel框架关联映射 Hibernate程序执行流程: 1.集合映射 需求:网络购物时,用户购买商品,填写地址 每个用户会有不确定的地址数目,或者只有一个或者有很多.这个时候不能把每条地址 ...

  10. [虾扯蛋] android界面框架-Window

    从纯sdk及framwork的角度看,android中界面框架相关的类型有:Window,WindowManager,View等.下面就以这几个类为出发点来概览下安卓开发的"界面架构&quo ...

随机推荐

  1. 【转】MYSQL入门学习之八:数据库及表的基本操作

    转载地址:http://www.2cto.com/database/201212/175867.html 一.操作数据库  www.2cto.com    1.查看数据库          show ...

  2. android技术总结

    1.要做一个尽可能流畅的ListView,你平时在工作中如何进行优化的? ①Item布局,层级越少越好,使用hierarchyview工具查看优化. ②复用convertView ③使用ViewHol ...

  3. MVC模式(Model View Controller)下实现数据库的连接,对数据的删,查操作

    MVC模式(Model View Controller): Model:DAO模型 View:JSP  在页面上填写java代码实现显示 Controller:Servlet 重定向和请求的转发: 若 ...

  4. asp.net c# 打开新页面或页面跳转

    1.最常用的页面跳转(原窗口被替代):Response.Redirect("XXX.aspx"); 2.利用url地址打开本地网页或互联网:Respose.Write(" ...

  5. Animator角色重复受击播放问题

    需要指定开始时间参数,否则Animator会默认当前已经在播放这个动画而忽略掉 CrossFade一样 gif: public class AnimatorDebug : MonoBehaviour ...

  6. 递归,动态规划,找最短路径,Help Jimmy

    题目链接:http://poj.org/problem?id=1661 解题报告: 1.老鼠每次来到一块木板上都只有两条路可以走,可以使用递归 #include <stdio.h> #in ...

  7. Combox控件初始化项的技巧

    有时候combox下拉项就是几条固定的,不需要做数据绑定,但是如果直接采用字符串集合编辑器的时候,SelectedValue貌似会不起作用. 于是简单的封装一下 /// <summary> ...

  8. Infragistics UltraGrid的使用

    OL SDK:http://help.infragistics.com/ 资料参考:http://blog.csdn.net/andy_212/article/details/4019895 http ...

  9. 【Java】常见的Set类型,HashSet、TreeSet、LinkedHashSet

    HashSet,锋芒毕露,我们最常用到.其他两个,我们较少用到,今天,我们看看他们的区别. import java.util.HashSet; import java.util.Set; public ...

  10. SpringMVC整合Tiles框架

    SpringMVC整合Tiles框架 Tiles组件 tiles-iconfig.xml Tiles是一个JSP布局框架. Tiles框架为创建Web页面提供了一种模板机制,它能将网页的布局和内容分离 ...