1
1
#3 .3 Go如何使得Web工作
2
- 前面小节介绍了如何通过Go搭建一个Web服务,我们可以看到简单的应用了一个net/http包就方便的搭建起来了。那么他底层到底是怎么做的呢?但是万变不离其宗,他离不开我们第一小节介绍的Web工作方式 。
2
+ 前面小节介绍了如何通过Go搭建一个Web服务,我们可以看到简单的应用了一个net/http包就方便的搭建起来了。那么他底层到底是怎么做的呢?万变不离其宗,Go也离不开我们第一小节介绍的Web工作方式 。
3
3
4
4
##对应web工作方式的几个概念
5
5
@@ -19,11 +19,11 @@ Handler:处理请求和生成返回信息的处理逻辑
19
19
20
20
![ ] ( images/3.3.http.png?raw=true )
21
21
22
- (1) 创建listen socket, 在指定的端口监听, 等待客户端请求的到来
22
+ (1) 创建listen socket, 在指定的端口监听, 等待客户端请求的到来。
23
23
24
- (2) listen socket接受客户端的请求, 得到client socket, 接下来通过client socket与客户端通信
24
+ (2) listen socket接受客户端的请求, 得到client socket, 接下来通过client socket与客户端通信。
25
25
26
- (3) 处理客户端的请求, 首先从client socket读取http请求的协议头, 如果是post协议, 还可能要读取客户端上传的数据, 然后跟给相应的handler处理请求, 准备好客户端需要的数据 , 通过client socket写给客户端
26
+ (3) 处理客户端的请求, 首先从client socket读取http请求的协议头, 如果是post协议, 还可能要读取客户端上传的数据, 然后扔给相应的handler处理请求, handler处理完毕准备好客户端需要的数据 , 通过client socket写给客户端。
27
27
28
28
这整个的过程里面我们只要了解清楚下面三个问题,也就知道Go是如何让Web运行起来了
29
29
@@ -33,9 +33,9 @@ Handler:处理请求和生成返回信息的处理逻辑
33
33
34
34
前面小节的代码里面我们可以看到,Go是通过一个函数来操作这个事情的` ListenAndServe ` 来监听起来的,这个底层其实这样处理的:初始化一个server对象,然后调用了` net.Listen("tcp", addr) ` ,也就是底层起的是TCP协议,然后监控了我们设置的端口。
35
35
36
- 监控之后如何接收客户端的请求呢?上面的监控端口之后,就调用了` srv.Serve(net.Listener) ` 函数,这个函数就是处理接收客户端的请求信息。这个函数里面起了一个` for{} ` ,里面通过Listener接收请求,然后起一个Conn,然后单独开了一个goroutine ,把这个请求的数据当做参数扔给这个conn去服务:` go c.serve() ` 。这个就是高并发体现了,用户来的请求都是goroutine去服务,相互不影响。
36
+ 监控之后如何接收客户端的请求呢?上面的监控端口之后,就调用了` srv.Serve(net.Listener) ` 函数,这个函数就是处理接收客户端的请求信息。这个函数里面起了一个` for{} ` ,首先通过Listener接收请求,其次起一个Conn,最后单独开了一个goroutine ,把这个请求的数据当做参数扔给这个conn去服务:` go c.serve() ` 。这个就是高并发体现了,用户来的请求都是goroutine去服务,相互不影响。
37
37
38
- 那么如何具体分配到相应的函数来处理请求呢?conn首先会解析request:` c.readRequest() ` ,然后获取相应的handler:` handler := c.server.Handler ` ,也就是我们刚才在调用函数` ListenAndServe ` 时候的第二个参数,我们前面例子传递的是nil,也就是为空,那么默认获取` handler = DefaultServeMux ` ,那么这个是哪里来的东西呢 ?对,这个东西就是路由器,也就是把相应的请求url对应请求函数的路由器,那么这个我们有设置过吗?有,我们调用的代码里面第一句不是调用了` http.HandleFunc("/", sayhelloName) ` 嘛。这个就是注册了相应的路由,url为"/"的请求到函数sayhelloName,DefaultServeMux会调用ServeHTTP方法,这个方法内部其实就是调用sayhelloName本身,最后通过写入response的信息反馈到客户端。
38
+ 那么如何具体分配到相应的函数来处理请求呢?conn首先会解析request:` c.readRequest() ` ,然后获取相应的handler:` handler := c.server.Handler ` ,也就是我们刚才在调用函数` ListenAndServe ` 时候的第二个参数,我们前面例子传递的是nil,也就是为空,那么默认获取` handler = DefaultServeMux ` ,那么这个变量用来做什么的呢 ?对,这个东西就是路由器,也就是把相应的请求url对应请求函数的路由器,那么这个我们有设置过吗?有,我们调用的代码里面第一句不是调用了` http.HandleFunc("/", sayhelloName) ` 嘛。这个就是注册了相应的路由,url为"/"的请求到函数sayhelloName,DefaultServeMux会调用ServeHTTP方法,这个方法内部其实就是调用sayhelloName本身,最后通过写入response的信息反馈到客户端。
39
39
40
40
至此我们的三个问题已经全部得到了解答,你现在对于Go如何让Web跑起来的是否已经大概清楚了呢?
41
41
0 commit comments