今天给大家分享一篇搭建GOwebserver,HelloWorld!!Go语言标准库——net/http是学习Go语言的一个很好的起点,Go语言官方文档详细介绍了我们今天学习的GoWeb服务器的搭建需要使用到官方提供的标准库net/httpGo语言,通过http包提供了HTTP客户端和服务端的实现。同时使用这个包可以方便的设置和操作web路由、静态文件、模板、cookies等数据。如果对http的概念不是很清楚,可以自行google。httppackagebuildswebserverpackagemainimport("fmt""net/http""strings""log")funcsayhelloName(whttp.ResponseWriter,r*http.Request){r.ParseForm()//解析参数,默认不用parsefmt.Println(r.Form)//信息为输出到服务器的打印信息fmt.Println("path",r.URL.Path)fmt.Println("scheme",r.URL.Scheme)fmt.Println(r.Form["url_long"])fork,v:=ranger.Form{fmt.Println("key:",k)fmt.Println("val:",strings.Join(v,""))}fmt.Fprintf(w,"HelloWrold!")//写入w是输出到客户端}funcmain(){http.HandleFunc("/",sayhelloName)//设置访问路由err:=http.ListenAndServe(":9090",nil)//设置监听端口iferr!=nil{log.Fatal("ListenAndServe:",err)}}以上代码在IDE中编译运行成功后,这次之后,我们可以监听9090端口的http链接请求。上图中,我们在浏览器中输入http://localhost:9090,可以看到在浏览器页面中输入了HelloWorld!这时候如果我们在浏览器地址后面加上一些参数,试试:http://localhost:9090?url_long=111&url_long=222,看看浏览器输出什么?服务器端的输出是什么?浏览器中的输出图像服务器端的输出图像我们已经看到了上面的代码,是不是还要写一个web服务器呢?很简单,调用http包的两个函数即可。如果你以前是.NET程序员,你可能会问,难道我们的IIS服务器不需要吗?Go就不需要这些,因为他直接监听TCP端口。我们看到Go已经用几行代码运行了一个web服务,这个web服务具有支持高并发的特性。现在已经构建了Web服务,现在让我们了解该服务是如何工作的。Web工作方式的几个概念以下是服务器段的概念。Request:用户请求的信息,用于解析用户的Request信息,包括post、get、cookie、url等信息Response:服务端需要反馈给客户端的信息Conn:每次请求的链接用户Handler:处理请求和生成返回信息的处理逻辑分析HTTP封装运行机制去实现Web服务在这个过程中,我们需要了解以下三个问题,那么我们就可以理解Go是如何让Web跑起来的,如何去监听到港口?通过上面的代码我们可以看出Go是通过一个函数ListenAndServe来处理这些事情的,这个底层其实是这样处理的:初始化一个server对象,然后调用net.Listen("tcp",addr),也就是,底层用TCP协议搭建服务,然后监听我们设置的端口。Gohttp包的源码,这里可以看到整个http的处理过程.Accept()ife!=nil{ifne,ok:=e.(net.Error);ok&&ne.Temporary(){iftempDelay==0{tempDelay=5*time.Millisecond}else{tempDelay*=2}ifmax:=1*time.Second;tempDelay>max{tempDelay=max}log.Printf("http:Accepterror:%v;retryingin%v",e,tempDelay)time.Sleep(tempDelay)continue}returne}tempDelay=0ifsrv。ReadTimeout!=0{rw.SetReadDeadline(time.Now().Add(srv.ReadTimeout))}ifsrv.WriteTimeout!=0{rw.SetWriteDeadline(time.Now().Add(srv.WriteTimeout))}c,err:=srv.newConn(rw)iferr!=nil{continue}goc.serve()}panic("notreached")}如何接收客户端请求?上述代码执行监听端口后,调用了srv.Serve(net.Listener)函数,该函数是处理从客户端接收到的请求信息。这个函数中设置了一个for{}。首先通过Listener接收请求,然后创建一个Conn,并单独开启一个goroutine,将请求的数据作为参数抛给conn去服务:goc.serve()。这就是高并发的体现。用户的每个请求都在一个新的goroutine中服务,而不会相互影响。如何分配处理程序?Conn会先解析request:c.readRequest(),然后得到对应的handler:handler:=c.server.Handler,也就是我们刚才调用函数ListenAndServe时的第二个参数,我们在上一个例子中传入的是nil,也就是为空,那么默认的handler=DefaultServeMux,那么这个变量是做什么用的呢?是的,这个变量就是一个router,用来匹配url跳转到它对应的handle函数,那么这个我们设置了吗?是的,我们调用的代码中不就是调用了http.HandleFunc("/",sayhelloName)吗。这个函数是注册请求/的路由规则。当请求uri为“/”时,路由会转到函数sayhelloName,DefaultServeMux会调用ServeHTTP方法。这个方法实际上调用了自己的sayhelloName,将response中写入的信息反馈给client。一个http连接的处理流程至此,我们的三个问题都得到了解答。你现在对Go如何让Web运行有基本的了解了吗?
