This is a creation in Article, where the information may have evolved or changed.
Preface
Because I have been engaged in Web server-side program development, so in learning Golang also want to start from the web here to learn, if the Golang is not clear how to build the environment friends can refer to my previous article Golang simple Introduction and Windows environment installation, deployment, Let's take a look at Golang's introduction to Web development: Building a simple Go Web server.
Note: This article draws on the content of the book "Go Web Programming" in Astaxie
Body
Go Language standard library-net/http
In learning the go language has a good starting point, the official go language document is very detailed, today we learn to build the Go Web server needs to use the official Go Language standard library net/http
, through the HTTP package provides HTTP client and server implementation. At the same time using this package can be very simple to the Web routing, static files, templates, cookies and other data set and operation. If the HTTP concept is not too clear to the friend can Google itself.
HTTP Package Build Web server
package mainimport ( "fmt" "net/http" "strings" "log")func sayhelloName(w http.ResponseWriter, r *http.Request) { r.ParseForm() //解析参数,默认是不会解析的 fmt.Println(r.Form) //这些信息是输出到服务器端的打印信息 fmt.Println("path", r.URL.Path) fmt.Println("scheme", r.URL.Scheme) fmt.Println(r.Form["url_long"]) for k, v := range r.Form { fmt.Println("key:", k) fmt.Println("val:", strings.Join(v, "")) } fmt.Fprintf(w, "Hello Wrold!") //这个写入到w的是输出到客户端的}func main() { http.HandleFunc("/", sayhelloName) //设置访问的路由 err := http.ListenAndServe(":9090", nil) //设置监听的端口 if err != nil { log.Fatal("ListenAndServe: ", err) }}
After we compile the above code and run successfully in the IDE, we can listen for HTTP link requests on port 9090 at this time.
, we entered the http://localhost:9090 in the browser and we can see the Hello world! in the browser page.
This time if we add some parameters after the browser address try: http://localhost:9090?url_long=111&url_long=222, see what the browser output? What is the server-side output?
Output picture in Browser
Server-side output picture
We see the above code, to write a Web server is not very simple, just call the HTTP packet of two functions can be.
If you had been. NET programmer, then you might ask, does our IIS server need it? Go just doesn't need this, because he listens to the TCP port directly.
We see that go has a Web service running with a few simple lines of code, and this Web service has features that support high concurrency. Now that the Web service has been built, let's see how a service works.
Several concepts of how Web works
The following are the concepts of server segments
- Request: The information requested by the user to resolve the user's request information, including post, get, cookie, url and other information
- Response: Information that the server needs to feed back to the client
- Conn: Each request link for the user
- Handler: processing logic to process requests and generate return information
Parsing HTTP packet run mechanism
Go implementation of Web services working mode flowchart
This process we need to understand the following three questions, it is clear how go to make the Web run up
- How do I listen to ports?
From the code above, we see that go is handled by a function ListenAndServe
, and this is where the bottom layer actually
Initialization of an server
object, then called net.Listen("tcp", addr)
, which is the bottom layer with the TCP protocol to build a service
And then monitor the ports that we set up.
Go HTTP package source code, here we can see the entire HTTP processing process
Func (SRV *server) Serve (l net. Listener) Error {defer l.close () var tempdelay time. Duration//How long-to-sleep on the Accept failure for {RW, E: = L.accept () if E! = nil {if NE, OK: = e. (NET. ERROR); Ok && ne. Temporary () {if Tempdelay = = 0 {tempdelay = 5 * time. Millisecond} else {Tempdelay *= 2} if Max: = 1 * time.s Econd; Tempdelay > Max {tempdelay = max} log. Printf ("Http:accept error:%v; Retrying in%v ", E, Tempdelay) time. Sleep (Tempdelay) Continue} return e} tempdelay = 0 if srv. ReadTimeout! = 0 {rw. Setreaddeadline (time. Now (). ADD (SRV. readtimeout))} if srv. WriteTimeout! = 0 {rw. Setwritedeadline (time. Now (). ADD (SRV. WriteTimeout)} c, err: = Srv.newconn (rw) If err! = nil {Continue} Go C.serve ()} Panic ("Not reached")}
- How do I receive client requests?
After the above code executes the monitoring port, the function is called, which srv.Serve(net.Listener)
is processing the request information of the receiving client. This function inside a for{}
, first through listener receive request, second create a Conn, finally opened a goroutine, the request data as parameters throw to this Conn to service: go c.serve()
. This is the high concurrency reflects that the user's every request is in a new goroutine to service, not affect each other.
- How do I allocate handler?
Conn First will parse request:c.readRequest()
, and then get the corresponding handler:handler := c.server.Handler
, that is, we just called the function ListenAndServe
when the second parameter, our previous example passed nil, that is, NULL, then the default to get handler = DefaultServeMux
, then what is this variable used to do? Yes, this variable is a router, it is used to match the URL to jump to its corresponding handle function, then we have set it? Yes, the first sentence in the code we call is not called http.HandleFunc("/", sayhelloName)
. This function is to register the request/routing rule, when the request URI is "/", the route will go to the function Sayhelloname,defaultservemux will call the Servehttp method, this method is actually called Sayhelloname itself, Finally, by writing the response feedback to the client.
An HTTP connection processing process
Now that our three questions have been answered, you have a basic understanding of how go makes the Web run.