Go Revel - server.go 源码分析
之前介绍了 Go Revel - main函数分析 http://www.cnblogs.com/hangxin1940/p/3263775.html
最后会调用 `revel.Run(*port)` 开启服务。
`server.go`源码 https://github.com/robfig/revel/blob/master/server.go
大致流程:

首先获取ip地址
address := HttpAddr
if port == 0 {
port = HttpPort
}
// If the port equals zero, it means do not append port to the address.
// It can use unix socket or something else.
if port != 0 {
address = fmt.Sprintf("%s:%d", address, port)
}
如果ip地址为0,则读取配置文件中的。
生成模板加载器:
MainTemplateLoader = NewTemplateLoader(TemplatePaths)
这个模板加载器包含了当前项目模板的路径。
根据配置文件是否开启热代码加载:
// The "watch" config variable can turn on and off all watching.
// (As a convenient way to control it all together.)
if Config.BoolDefault("watch", true) {
MainWatcher = NewWatcher()
Filters = append([]Filter{WatchFilter}, Filters...)
}
这里会生成一个`Watcher`,并将它加入过滤器链,`Watcher`符合Filter接口。它会对监听目录的中文件的任何更改作出响应。
根据配置文件是否开启模板热加载:
// If desired (or by default), create a watcher for templates and routes.
// The watcher calls Refresh() on things on the first request.
if MainWatcher != nil && Config.BoolDefault("watch.templates", true) {
MainWatcher.Listen(MainTemplateLoader, MainTemplateLoader.paths...)
} else {
MainTemplateLoader.Refresh()
}
同上,它会对模板目录进行监控
开启HTTP服务:
Server = &http.Server{
Addr: address,
Handler: http.HandlerFunc(handle),
}
处理所有向`OnAppStart`注册过的方法:
runStartupHooks()
开始监听并等待连接:
if HttpSsl {
ERROR.Fatalln("Failed to listen:",
Server.ListenAndServeTLS(HttpSslCert, HttpSslKey))
} else {
ERROR.Fatalln("Failed to listen:", Server.ListenAndServe())
}
这里会视情况来开启ssl
请求处理器:
// This method handles all requests. It dispatches to handleInternal after
// handling / adapting websocket connections.
func handle(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Upgrade") == "websocket" {
websocket.Handler(func(ws *websocket.Conn) {
r.Method = "WS"
handleInternal(w, r, ws)
}).ServeHTTP(w, r)
} else {
handleInternal(w, r, nil)
}
}
func handleInternal(w http.ResponseWriter, r *http.Request, ws *websocket.Conn) {
var (
req = NewRequest(r)
resp = NewResponse(w)
c = NewController(req, resp)
)
req.Websocket = ws
Filters[0](c, Filters[1:])
if c.Result != nil {
c.Result.Apply(req, resp)
}
}
所有的http请求都会在这里被处理。
首先会判断是否为`websocket`链接,如果是则打上标记,并当作websocket处理,最终都会调用`handleInternal`。
在`handleInternal`中,首先会处理过滤器链:
Filters[0](c, Filters[1:])
`Filters`是一个切片,存储`Filter`类型的方法
type Filter func(c *Controller, filterChain []Filter)
`Filter`是一个固定参数的方法,并且内部方法实现为级联递归调用。每次掉用,会传入`controller`以及当前`Filters`长度-1的一个切片,在方法最后会递归调用下去,直到传入的`Filters`切片没有元素。
自己实现的`Controller`中的方法被调用之前,所有的请求数据都会被`Filter`过滤一边,比如根据请求信息来生成路由信息,根据请求参数来转换为正确的自定义类型,运行拦截器等等。
最后,会运行:
c.Result.Apply(req, resp)
`controller`的`Result`字段会在运行过滤器链时被赋值,有可能是处理路由时的`Result`(比如404),也有可能是自定义`controller`中的`Result`(正常处理)
Go Revel - server.go 源码分析的更多相关文章
- kestrel Server的源码分析
今天这一篇博客讲的是.net core 自带的kestrel server,当你开发微服务k8s部署在linux环境下,一般默认开启这个高性能服务,如果大家之前看过我的owin katana的博客,会 ...
- udhcp server端源码分析1--文件组织结构
1:dhcpd.c udhcpd_main函数是整个程序的入口,依次完成的主要工作有读取配置文件信息至全局结构体.记录程序pid number.初始化lease链表.将程序作为daemon运行.死循环 ...
- Go Revel - Filter(过滤器)源码分析
在 Go Revel - server.go 源码分析 http://www.cnblogs.com/hangxin1940/p/3265538.html 说到revel框架很多重要的东西都Filte ...
- dubbo源码分析4-基于netty的dubbo协议的server
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
- Eureka 源码分析之 Eureka Server
文章首发于公众号<程序员果果> 地址 : https://mp.weixin.qq.com/s/FfJrAGQuHyVrsedtbr0Ihw 简介 上一篇文章<Eureka 源码分析 ...
- dubbo源码分析6-telnet方式的管理实现
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
- dubbo源码分析1-reference bean创建
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
- dubbo源码分析2-reference bean发起服务方法调用
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
- dubbo源码分析3-service bean的创建与发布
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
随机推荐
- C# 创建windows 服务
1. 新建项目 1.1 右键解决方案 – 添加 – 新建项目 1.2 已安装模板 - windows - windows服务 – 输入名称 – 点击 ”确定” 2. 添加相应的 ...
- SQL 中的 UNION 和UNION ALL 的区别
UNION表示“并”,当用的时候,系统会自动将重复的元组去掉,如果要保留重复元组则就用UNION ALL UNION 会合并重复数据,(由于要合并重复,该操所 隐藏着一个 排序的操作.)UNION A ...
- 第二篇:呈现内容_第一节:Control呈现
一.Control的呈现过程 在上个章节““生死有序”的控件生命周期”中,我们提到Render是控件开发的主角,但在控件树的“合成模式(Composite)”部分这位主角却缺席了(戏份太多的缘由).哦 ...
- .net framework多个版本在IIS服务器上时应注意-重新注册IIS-错误Server Application Unavailable
今天客户一个附件上传的应用程序报错,服务器安装了.net 4.0 framework(还有1.0和2.0版本),因为有网站程序需要用到2.0,配置好站点后,附件程序是用的2.0,Mail程序选择版本为 ...
- MySql(九):MySQL性能调优——Schema设计的性能优化
一.高效的模型设计 先了解下数据库设计的三大范式 第一范式:要求有主键,并且要求每一个字段原子性不可再分 第二范式:要求所有非主键字段完全依赖主键,不能产生部分依赖 第三范式:所有非主键字段和主键字段 ...
- android辅助开发工具包介绍
辅助开发工具包(ADK)是为硬件制造商和业余爱好者准备的参考实现.硬件制造商和业余爱好者可以使用此工具包作为开发Android辅助设备的起点.每一个ADK发行版都将提供源代码和硬件规格,以使整个辅助设 ...
- NSString和NSMutablestring,copy和strong(转载)
1.http://www.cocoachina.com/ios/20150512/11805.html 2.http://blog.csdn.net/winzlee/article/details/5 ...
- fastdfs 图片服务器 使用java端作为客户端上传图片
之前有说道搭建fastdfs作为图片服务器,但是没有说明如何真正在代码里调用,那么今天大致讲一下,如何使用java客户端进行上传 首先你得要有一个客户端,导入到eclipse中即可 git地址如下: ...
- Atitti 固化数据库表结构方案
Atitti 固化数据库表结构方案 1. 固化数据库表结的重要意义1 2. 如何固化表结构1 2.1. 向上抽象一层,以动词有目标,以名词为存储对象.1 2.2. 数据类型datatype字段:这个用 ...
- Linux学习笔记(九)
<span style="font-size:18px;">本人使用的是centos 因为用使用些特殊命令.不得不改动系统的时间这里总结例如以下: date 查看系统时 ...