Go Web Programming One: Go Web basics

Source: Internet
Author: User
Tags data structures http request socket web services

Original link http://ironxu.com/779

Go Web Basic concepts and code reading 1. Go to build a simple Web service

The Go language provides a complete net/http package that can be easily built with HTTP packets to run a Web service. At the same time using this package can be very simple to the Web routing, static files, templates, cookies and other settings and operations.

$GOPATH/src/github.com/ironxu/go_note/web/basic/server.go Source code is as follows:

The HTTP package establishes the Web server packages
main

import (
    "FMT"
    "Log" "
    net/http"
)

func sayhelloname (w http. Responsewriter, R *http. Request) {
    r.parseform ()
    FMT. Println ("Path:", R.url. Path)
    FMT. fprintf (w, "Hello Go")
}

func main () {
    http. Handlefunc ("/", Sayhelloname)
    err: = http. Listenandserve (": 9090", nil)
    if err! = Nil {
        log. Fatal ("Listenandserver:", err)
    }
}

Go run server.go can start the HTTP service and use the browser to open http://localhost:9090 to view the output. 2. Go Web Services explained

This section describes the Go Web services underlying implementation, including registration Routing and request handling 2.1 HTTP packet run mechanism

The Go Implementation Web service process creates a listen Socket, listens on the specified port, waits for a client request to arrive. The Listen socket accepts the client's request, obtains the customer socket, and then communicates with the client through the customer socket. Processing the client's request, first read the HTTP request from the client socket, then hand over to the corresponding handler processing request, and finally the handler processed data, through the client socket to clients.

This involves the concept of server-side: Request: User requested information to resolve the user's request information, including post, get, cookie, url and other information Conn: the user's every request link Handler: Processing the request and generating return information processing logic Response: Server needs feedback to clients 2.2 Service listener and request processing process

Go is through a Listenandserve listener service, underlying processing: initializing a server object and then calling net. Listen ("tcp", addr), monitor the ports we set up.

After monitoring the port, call srv. Serve (NET. Listener) function to handle request information from the receiving client. First receives the request through the listener, Second creates a conn, finally opened a goroutine, the request data as the parameter throws to this conn to serve. Go C.serve () Each request of the user is in a new goroutine to serve, does not affect each other.

Assign the appropriate function to process the request: Conn first parses Request:c.readrequest () and then gets the corresponding Handler:handler: = C.server.handler, which is the calling function Listenandserve The second parameter of the time, the example passes nil, which is null, then the default gets handler = Defaultservemux. Defaultservemux is a router that matches the URL to jump to its corresponding handle function

Call HTTP. The Handlefunc ("/", sayhelloname) function is to register the request/Routing rule, register the URL and handle function to the DEFAULTSERVEMUX variable, and finally call Defaultservemux's Servehttp method, This method internally calls the handle function.

The flowchart is as follows:

3. Web Service Code Implementation 3.1 routing registration Code

1 calls HTTP. Handlefunc ("/", Sayhelloname) registered routing

/usr/local/go/src/net/http/server.go:2081
func handlefunc (pattern string, handler func (Responsewriter, * Request) {
    Defaultservemux.handlefunc (pattern, handler)//Defaultservemux type *servemux
}

2 Using the default Servemux

: 2027
func (Mux *servemux) Handlefunc (pattern string, handler func (Responsewriter, *request)) {
    mux. Handle (Pattern, Handlerfunc (handler))
}

3 Registering a Routing policy defaultservemux

Func (Mux *servemux) Handle (pattern string, handler handler) {
    mux.mu.Lock ()
    defer mux.mu.Unlock ()

    ...

    Mux.m[pattern] = muxentry{explicit:true, H:handler, Pattern:pattern}

    if pattern[0]! = '/' {
        mux.hosts = tr UE
    }

    ...
}

Involving data structures

: 1900 Servemux Default instance is Defaultservemux
type servemux struct {
    mu    sync. Rwmutex//Lock, because the request involves concurrent processing, it requires a locking mechanism
    m     map[string]muxentry//Routing rules, a string corresponding to a MUX entity, where string is the registered route expression
    hosts bool//whether in arbitrary rules with host information
}

Type muxentry struct {
    explicit bool
    h        Handler//route processor
    pattern  string  //URL match regular
}

type Handler interface {
    servehttp (responsewriter, *request)
}
3.2 Service Monitoring Code

1 Call Err: = http. Listenandserve (": 9090", nil) listening port

/usr/local/go/src/net/http/server.go:2349
func listenandserve (addr string, handler handler) error {
    server : = &server{addr:addr, Handler:handler}//Handler is empty
    return Server. Listenandserve ()
}

Create a server object and call the server's Listenandserve ()

2 Listening to TCP ports

: 2210
func (SRV *server) listenandserve () error {
    addr: = srv. Addr
    If Addr = = "" {
        Addr = ": http"
    }
    ln, err: = Net. Listen ("tcp", addr)
    if err! = Nil {
        return err
    }
    return srv. Serve (Tcpkeepalivelistener{ln. ( *net. TcpListener)})
}

3 Receiving Requests

: 2256
func (SRV *server) Serve (l net. Listener) Error {
    defer l.close () ...

    Basectx: = Context. Background ()
    CTX: = context. Withvalue (Basectx, Servercontextkey, SRV)
    CTX = context. Withvalue (CTX, Localaddrcontextkey, L.addr ())
    for {
        rw, E: = L.accept ()//1. Listener Receive request
        if E! = nil {
            ...
        }
        Tempdelay = 0
        c: = Srv.newconn (rw)//2. Create *conn
        c.setstate (C.RWC, statenew)//Before Serve can return
        go C.serve (CTX)//3. City a goroutine, the request data is passed as a parameter to Conn, the new goroutine to handle the request
    }
}

4 Goroutine Processing Request

Serve a new connection.
Func (c *conn) serve (CTX context. Context) {
    ...
    http/1.x on.

    C.R = &CONNREADER{R:C.RWC}
    c.bufr = Newbufioreader (C.R)
    C.BUFW = Newbufiowritersize (checkconnerrorwriter {c}, 4<<10)

    ctx, Cancelctx: = context. Withcancel (CTX)
    defer cancelctx () for

    {
        W, err: = C.readrequest (CTX)//1. Get Request data
        ... Serverhandler{c.server}. Servehttp (W, w.req)//2. Process the request Serverhandler, corresponding to the 5th step below
        w.cancelctx ()
        if c.hijacked () {
            return
        }
        w.finishrequest ()// 3. Return response result
        if!w.shouldreuseconnection () {
            if W.requestbodylimithit | | w.closedrequestbodyearly () {
                C.closewriteandwait ()
            }
            return
        }
        c.setstate (C.RWC, Stateidle)
    }
}

5 Processing Requests

Func (Sh serverhandler) servehttp (rw responsewriter, req *request) {
    handler: = Sh.srv.Handler
    If handler = = Nil {
        handler = defaultservemux//Servemux
    }
    If req. RequestUri = = "*" && req. Method = = "OPTIONS" {
        handler = globaloptionshandler{}
    }
    handler. Servehttp (rw, req)
}

5.1 handler. Servehttp (rw, req)

Func (Mux *servemux) servehttp (w responsewriter, R *request) {
    if R.requesturi = = "*" {
        if R.protoatleast (1, 1) {
            W.header (). Set ("Connection", "Close")
        }
        W.writeheader (statusbadrequest)
        return
    }
    h, _: = Mux. Handler (R)//Handlerfunc, Handler
    h.servehttp (W, R)
}

5.2 Performing processing

Servehttp calls F (W, R).
Func (f Handlerfunc) servehttp (w responsewriter, R *request) {
    f (W, R)
}

Types of data involved

Type Server struct {
    Addr         string        //TCP address to listen on, ": http" if empty
    Handler      Handler       // Handler to invoke, HTTP. Defaultservemux if nil
    readtimeout time  . Duration//maximum Duration before timing out read of the request
    writetimeout time. Duration//maximum Duration before timing out write of the response
    ...
}

Type conn struct {
    server *server//server is the server on which the connection arrived.
    RWC net. Conn//RWC is the underlying network connection. It is usually of type *net. Tcpconn or *tls.conn.
    REMOTEADDR string//This is the value of a Handler ' s (*request). Remoteaddr.
    Mu sync. Mutex//MU guards Hijackedv, use of BUFR, (*response). Closenotifych.
    ...
}

Type Serverhandler struct {
    srv *server
}
3.3 The Go code execution process

Call Http.handlefunc, in order to do a few things: Call the Defaultservemux Handlefunc call Defaultservemux handle to Defaultservemux] Add corresponding handler and routing rules in Muxentry

Call HTTP. Listenandserve (": 9090", nil), in order to do a few things: Instantiate the server calling the server's Listenandserve () call net. The Listen ("TCP", addr) listener port initiates a for loop in which the accept request instantiates a conn for each request and opens a goroutine for the request to service go C.serve () reads the contents of each request W, err: = C.readrequest () Determines whether the handler is empty, if no handler is set (this example does not set handler), handler is set to Defaultservemux call handler Servehttp In this example, the following goes into defaultservemux.servehttp according to request select Handler, and enters into this handler servehttp Mux.handler (R). Servehttp (W, R) Select handler:
A determine if there is a route to satisfy this request (looping through Servermux's muxentry)
B If there is a route to satisfy, call this route handler Servehttp
C If no route is met, call Notfoundhandler's Servehttp 4. Custom Routing Implementation

Define the type implementation Servehttp method, you can implement the custom route

Package main

Import (
    "FMT"
    "Log" "
    net/http"
)

type mymux struct {}

func (P *mymux) Servehttp (w http. Responsewriter, R *http. Request) {
    if r.url. Path = = "/" {
        sayhelloname (W, R)
        return
    }

    http. NotFound (W, R)
    return
}


func sayhelloname (w http. Responsewriter, R *http. Request) {
    r.parseform ()
    FMT. Println ("Path:", R.url. Path)
    FMT. fprintf (w, "Hello Go")
}

func main () {
    mux: = &mymux{}
    Err: = http. Listenandserve (": 9090", MUX)
    if err! = Nil {
        log. Fatal ("Listenandserver:", err)
    }
}
Reference3.2 Go to build a Web server 3.3 go how to make the Web Work 3.4 go HTTP package detailed

You can follow my Weibo for more information: @ Just small yards farm

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.