使用Go写后端架构(一)
首先, go语言的编译器包含了所有素需要的包,因此十分方便写后台,甚至不需要使用框架,就可以轻松搭建。在学习Go语言有一个很好的起点,Go语言官方文档很详细,今天我们学习的Go Web服务器的搭建就需要用到Go语言官方提供的标准库 net/http,通过http包提供了HTTP客户端和服务端的实现。同时使用这个包能很简单地对web的路由,静态文件,模版,cookie等数据进行设置和操作。如果对http概念不是太清楚的朋友可以自行google。
第一步:导入相关库文件:
import (
"net/http"
"html/template"
//"encoding/json"
"fmt"
)
第二步:创建服务器结构体:与C++类似:
type Serverstruct {
ServerName string
ServerIP string
}
第三步:绑定端口,设置post,get方法:
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":9002", nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
if r.Method =="GET" {
t, err := template.ParseFiles("test.html")
if err != nil {
fmt.Fprintf(w,"parse template error: %s", err.Error())
return
}
t.Execute(w, nil)
}else if r.Method =="POST" {
r.ParseForm()
username := r.Form["username"]
password := r.Form["password"]
fmt.Printf("username = %s, password = %s", username, password)
}
}
使用go写后端最关键的两个问题:
如何接收客户端请求?
上面代码执行监控端口之后,调用了srv.Serve(net.Listener)函数,这个函数就是处理接收客户端的请求信 息。这个函数里面起了一个for{},首先通过Listener接收请求,其次创建一个 Conn,最后单独开了一个 goroutine,把这个请求的数据当做参数扔给这个conn去服务:go c.serve()。这 个就是高并发体现了, 用户的每一次请求都是在一个新的goroutine去服务,相互不影响。
如何分配handler?
conn首先会解析request:c.readRequest(),然后获取相应的handler:handler := c.server.Handler,也就是我们刚才在调用函数ListenAndServe时候的第二个参数,我们前面例子传递的是nil,也就是为空,那么默认获取handler = DefaultServeMux,那么这个变量用来做什么的呢?对,这个变量就是一个路由器,它用来匹配url跳转到其相应的handle函数,那么这个我们有设置过吗?有,我们调用的代码里面第一句不是调用了http.HandleFunc("/", sayhelloName)嘛。这个作用就是注册了请求/的路由规则,当请求uri为"/",路由就会转到函数sayhelloName,DefaultServeMux会调用ServeHTTP方法,这个方法内部其实就是调用sayhelloName本身,最后通过写入response的信息反馈到客户端。
代码如下:
package main
import (
"net/http"
"html/template"
//"encoding/json"
"fmt"
)
type Serverstruct {
ServerName string
ServerIP string
}
func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":9002", nil)
}
func handler(w http.ResponseWriter, r *http.Request) {
if r.Method =="GET" {
t, err := template.ParseFiles("test.html")
if err != nil {
fmt.Fprintf(w,"parse template error: %s", err.Error())
return
}
t.Execute(w, nil)
}else if r.Method =="POST" {
r.ParseForm()
username := r.Form["username"]
password := r.Form["password"]
fmt.Printf("username = %s, password = %s", username, password)
}
}