公司网站后缀,椒江哪里可以做公司网站,郑州网络推广代理顾问,云南网站制作多少钱使用Go语言的库非常容易实现一个Web服务器#xff0c;用来响应像fetch那样的客户端请求。本节将展示一个迷你服务器#xff0c;返回访问服务器的URL的路径部分。例如#xff0c;如果请求的URL是http://localhost:8000/hello#xff0c;响应将是URL.Path/hello。…使用Go语言的库非常容易实现一个Web服务器用来响应像fetch那样的客户端请求。本节将展示一个迷你服务器返回访问服务器的URL的路径部分。例如如果请求的URL是http://localhost:8000/hello响应将是URL.Path/hello。//server1.go这是一个迷你回声服务器packagemainimport(fmtlognet/http)funcmain(){http.HandleFunc(/,handler)//回声请求调用处理程序log.Fatal(http.ListenAndServe(localhost:8000,nil))}//处理程序回显请求URLr的路径部分funchandler(whttp.ResponseWriter,r*http.Request){fmt.Fprintf(w,URL.Path%qn,r.URL.Path)}这个程序只有寥寥几行代码因为库函数做了大部分工作。main函数将一个处理函数和以“/”开头的URL链接在一起代表所有的URL使用这个函数处理然后启动服务器监听进入8000端口处的请求。一个请求由一个http.Request类型的结构体表示它包含很多关联的域其中一个是所请求的URL。当一个请求到达时它被转交给处理函数并从请求的URL中提取路径部分(/hello)使用fmt.Printf格式化然后作为响应发送回去。让我们在后台启动服务器。在MacOSX或者Linux上在命令行后添加一个符号在微软Windows上不需要符号而需要单独开启一个独立的命令行窗口。$gorunsrc/gopl.io/chl/serverl/main.go可以从命令行发起客户请求$gobuildgopl.io/ch5/fetch$./fetchhttp://localhost:8000URL.PathT$./fetchhttp://localhost:8000/helpURL.Path/help另外还可以通过浏览器进行访问如下图所示。图来自回声服务器的响应为服务器添加功能很容易。一个有用的扩展是一个特定的URL它返回某种排序的状态。例如这个版本的程序完成和回声服务器一样的事情但同时返回请求的数量URL/count请求返回到现在为止的个数去掉/count请求本身//server2.go这是一个迷你的回声和计数器服务器packagemainimport(fmtlognet/httpsync)varmusync.Mutexvarcountintfuncmain(){http.HandleFunc(/,handler)http.HandleFunc(/count,counter)log.Fatal(http.ListenAndServe(localhost:8000,nil))}//处理程序回显请求的URL的路径部分funchandler(whttp.ResponseWriter,r*http.Request){mu.Lock()countmu.Unlock()fmt.Fprintf(w,URL.Path%qn,r.URL.Path)}//counter回显目前为止调用的次数funccounter(whttp.ResponseWriter,r*http.Request){mu.Lock()fmt.Fprintf(w,Count%dn,count)mu.Unlock()}这个服务器有两个处理函数通过请求的URL来决定哪一个被调用请求/count调用counter其他的调用handler。以“/”结尾的处理模式匹配所有含有这个前缀的URL。在后台对于每个传入的请求服务器在不同的goroutine中运行该处理函数这样它可以同时处理多个请求。然而如果两个并发的请求试图同时更新计数值count它可能会不一致地增加程序会产生一个严重的竞态bug。为避免该问题必须确保最多只有一个goroutine在同一时间访问变量这正是mu.Lock()和mu.Unlock()语句的作用。作为一个更完整的例子处理函数可以报告它接收到的消息头和表单数据这样可以方便服务器审查和调试请求//处理程序回显HTTP请求funchandler(whttp.ResponseWriter,r*http.Request){fmt.Fprintf(w,%s%s%sn,r.Method,r.URL,r.Proto)fork,v:ranger.Header{fmt.Fprintf(w,Header[%q]%qn,k,v)}fmt.Fprintf(w,Host%qn,r.Host)fmt.Fprintf(w,RemoteAddr%qn,r.RemoteAddr)iferr:r.ParseForm();err!nil{log.Print(err)}fork,v:ranger.Form{fmt.Fprintf(w,Form[%q]%qn,k,v)}}这里使用http.Request结构体的成员来产生类似下面的输出GET/?qqueryHTTP/1.1Header[Accept-Encoding][gzip,deflate,sdch]Header[Accept-Language][en-US,en;q0.8]Header[Connection][keep-alive]Header[Accept][text/html,application/xhtmlxml,application/xml;…]Header[User-Agent][Mozilla/5.0(Macintosh;IntelMacOSX10_7_5)…]Hostlocalhost:8000RemoteAddr127.0.0.1:59911Form[q][query]注意这里是如何在if语句中嵌套调用ParseForm的。Go允许一个简单的语句(如一个局部变量声明)跟在if条件的前面这在错误处理的时候特别有用。也可以这样写err:r.ParseForm()iferr!nil{log.Print(err)}这些程序中我们看到了作为输出流的三种非常不同的类型。fetch程序复制HTTP响应到文件os.Stdout像lissajous一样fetchall程序通过将响应复制到ioutil.Discard中进行丢弃(在统计其长度时)Web服务器使fmt.Fprintf通过写入http.Responsewriter来让浏览器显示。尽管三种类型细节不同但都满足一个通用的接口(interface)该接口允许它们按需使用任何一种输出流。该接口称为io.Writer。我们来看一下整合Web服务器和lissajous函数是一件多么容易的事情这样GIF动画将不再输出到标准输出而是HTTP客户端。简单添加这些行到Web服务器handler:func(whttp.ResponseWriter,r*http.Request){lissajous(w)}http.HandleFunc(/,handler)或者也可以http.HandleFunc(/,func(whttp.ResponseWriter,r*http.Request){lissajous(w)})上面HandleFunc函数中立即调用的第二个参数是函数字面量这是一个在该场景中使用它时才定义的匿名函数。一旦完成这个改变就可以通过浏览器访问http://localhost:8000。每次加载页面将看到一个类似下图的动画。图浏览器中的动态利萨茹图形