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. coco2dx服务器简单例子

    实现的单个socket例子,了解socket原理. 先创建一个win32的项目(命令行的),作为服务端 // SocketServer.cpp : 定义控制台应用程序的入口点.// #include ...

  2. [团队项目]第二个冲刺 看板和燃尽图 Sprint2 6.8/6.9/6.10/6.11/6.12/6.13/6.14

    1.开始一个新的冲刺: 起止:2016.6.1~2016.6.14 按照以下过程进行 ProductBacklog:继续向下细化 Sprint 计划会议:确定此次冲刺要完成的目标 Sprint Bac ...

  3. java 用socket制作一个简易多人聊天室

    代码: 服务器端Server import java.io.*; import java.net.*; import java.util.ArrayList; public class Server{ ...

  4. corefile的设置与使用

    一.简介 corefile是Linux下程序崩溃时生成的文件,可以用来分析程序崩溃的原因,因为它内部包含了程序崩溃时的堆栈信息. 二.corefile的设置 默认情况下,程序崩溃是不会生成corefi ...

  5. bash中一些基础知识

    bash是linux操作系统的shell.以下是Multi-Perspective Sentence Similarity Modeling论文实现时碰到的一个bash: #!/bin/bash py ...

  6. 2016年10月30日 星期日 --出埃及记 Exodus 19:15

    2016年10月30日 星期日 --出埃及记 Exodus 19:15 Then he said to the people, "Prepare yourselves for the thi ...

  7. bouncy castle的配置

    Bouncy Castle 是一种用于 Java 平台的开放源码的轻量级密码术包.它支持大量的密码术算法,并提供 JCE 1.2.1 的实现.因为 Bouncy Castle 被设计成轻量级的,所以从 ...

  8. log4net使用(winform)

    有时候 会出现错误 :如 log4net 错误 2 未能找到类型或命名空间名称“log4net”(是否缺少 using 指令或程序集引用?) 解决 方法 :http://q.cnblogs.com/q ...

  9. JavaScript(1)

    JavaScript(1) 第一次见到JavaScript的时候,看到了熟悉的"Java",原来都是骗人的,李鬼不是李逵呀=.= 然而发现这个东西还是特别实用的,和Java比起来它 ...

  10. MySQL基础(三)——约束

    MySQL基础(三)--约束 约束是在表上强制执行的数据校验规则,主要用于维护表中数据的完整性以及当数据之间有以来关系时,保护相关的数据不会被删除. 根据约束对列的限制,可以划分为:单列约束(只约束一 ...