Go程序设计语言1.7 一个Web服务器

1.7 一个Web服务器


使用Go的库非常容易实现一个Web服务器,用来响应像fetch那样的客户端请求。本节将展示一个迷你服务器,返回访问服务器的URL的路径部分。例如,如果请求的URL是http://localhost:8000/hello,响应将是URL.Path = "/hello"。

 

 

这个程序只有寥寥几行代码,因为库函数做了大部分工作。main函数将一个处理函数和以/开头的URL链接在一起,代表所有的URL使用这个函数处理,然后启动服务器监听进入8000端口处的请求。一个请求由一个http.Request类型的结构体表示,它包含很多关联的域,其中一个是所请求的URL。当一个请求到达时,它被转交给处理函数,并从请求的URL中提取路径部分(/hello),使用fmt.Printf格式化,然后作为响应发送回去。Web服务器将在7.7节进行详细讨论。

让我们在后台启动服务器。在Mac OS X或者Linux上,在命令行后添加一个&符号;在微软Windows上,不需要&符号,而需要单独开启一个独立的命令行窗口。

 

可以从命令行发起客户请求:

 

另外,还可以通过浏览器进行访问,如图1-2所示。

为服务器添加功能很容易。一个有用的扩展是一个特定的URL,它返回某种排序的状态。例如,这个版本的程序完成和回声服务器一样的事情,但同时返回请求的数量;URL

/count请求返回到现在为止的个数,去掉/count请求本身:

 

 

 

 

这个服务器有两个处理函数,通过请求的URL来决定哪一个被调用:请求/count调用counter,其他的调用handler。以/结尾的处理模式匹配所有含有这个前缀的URL。在后台,对于每个传入的请求,服务器在不同的goroutine中运行该处理函数,这样它可以同时处理多个请求。然而,如果两个并发的请求试图同时更新计数值count,它可能会不一致地增加,程序会产生一个严重的竞态bug(参考9.1节)。为避免该问题,必须确保最多只有一个goroutine在同一时间访问变量,这正是mu.Lock()和mu.Unlock()语句的作用。第9章将更细致地讨论共享变量的并发访问。

作为一个更完整的例子,处理函数可以报告它接收到的消息头和表单数据,这样可以方便服务器审查和调试请求:

 

这里使用http.Request结构体的成员来产生类似下面的输出:

 

 

注意这里是如何在if语句中嵌套调用ParseForm的。Go允许一个简单的语句(如一个局部变量声明)跟在if条件的前面,这在错误处理的时候特别有用。也可以这样写:

 

但是合并的语句更短而且可以缩小err变量的作用域,这是一个好的实践。2.7节将介绍作用域。

这些程序中,我们看到了作为输出流的三种非常不同的类型。fetch程序复制HTTP响应到文件os.Stdout,像lissajous一样;fetchall程序通过将响应复制到ioutil.Discard中进行丢弃(在统计其长度时);Web服务器使用fmt.Fprintf通过写入http.ResponseWriter来让浏览器显示。

尽管三种类型细节不同,但都满足一个通用的接口(interface),该接口允许它们按需使用任何一种输出流。该接口(称为io.Writer)将在7.1节进行讨论。

Go的接口机制是第7章的内容,但是为了说明它可以做什么,我们来看一下整合Web服务器和lissajous函数是一件多么容易的事情,这样GIF动画将不再输出到标准输出而是HTTP客户端。简单添加这些行到Web服务器:

 

或者也可以:

 

上面HandleFunc函数中立即调用的第二个参数是函数字面量,这是一个在该场景中使用它时才定义的匿名函数,这将在5.6节进一步解释。

一旦你完成这个改变,就可以通过浏览器访问http://localhost:8000。每次加载页面,你将看到一个类似图1-3的动画。

练习1.12:修改利萨茹服务器以通过URL参数读取参数值。例如,你可以通过调整它,使得像http://localhost:8000/?cycles=20这样的网址将其周期设置为20,以替代默认的5。使用strconv.Atoi函数来将字符串参数转化为整型。可以通过go doc strconv.Atoi来查看文档。

时间: 2024-06-06 15:45:45

Go程序设计语言1.7 一个Web服务器的相关文章

利用Go语言初步搭建一个web应用的教程

  这篇文章主要介绍了利用Go语言初步搭建一个web应用的教程,由于很多国人盲目迷信谷歌,导致Go语言在国内的人气远超国外...需要的朋友可以参考下 1.Abstract 在学习web开发的过程中会遇到很多困难,因此写了一篇类似综述类的文章.作为路线图从web开发要素的index出发来介绍golang开发的学习流程以及Example代码. 在描述中多是使用代码来描述使用方法不会做过多的说明.最后可以方便的copy代码来实现自己的需求. 本文适应对象: 对web开发有一定经验的人 能够灵活使用aj

自己动手开发一个 Web 服务器(二)

自己动手开发一个 Web 服务器(二) 在<自己动手开发一个 Web 服务器(一)>中,我给大家留了一个问题:如何在不对服务器代码作任何修改的情况下,通过该服务器运行Djando应用.Flask应用和Pyramid应用,同时满足这些不同网络框架的要求?读完这篇文章,你就可以回答这个问题了. 以前,你选择的Python网络框架将会限制所能够使用的 Web 服务器,反之亦然.如果框架和服务器在设计时就是可以相互匹配的,那你就不会面临这个问题: 但是如果你试图将设计不相匹配的服务器与框架相结合,那么

自己动手开发一个 Web 服务器(三)

自己动手开发一个 Web 服务器(三) 在第二部分中,你开发了一个能够处理HTTPGET请求的简易WSGI服务器.在上一篇的最后,我问了你一个问题:"怎样让服务器一次处理多个请求?"读完本文,你就能够完美地回答这个问题.接下来,请你做好准备,因为本文的内容非常多,节奏也很快.文中的所有代码都可以在Github仓库下载. 首先,我们简单回忆一下简易网络服务器是如何实现的,服务器要处理客户端的请求需要哪些条件.你在前面两部分文章中开发的服务器,是一个迭代式服务器iterative serv

Stunnix Advanced Web Server for CD-ROMs 5.9发布 一个Web服务器

Stunnix http://www.aliyun.com/zixun/aggregation/3415.html">Advanced Web Server for CD-ROMs是一个Web服务器,用于网站上的CD-ROM.DVD.FlashDisks和其他只读媒体,也可用于任何标准的系统.通过MySQL或SQLite数据库驱动,网站的脚本支持PHP.Python.Java或Perl.所有必需的软件程序设计都驻留在CD-ROM,以避免需要用户在计算机上安装软件.Web服务核心是基于Apa

自己动手开发一个 Web 服务器(一)

自己动手开发一个 Web 服务器(一) 有一天,一位女士散步时经过一个工地,看见有三个工人在干活.她问第一个人,"你在做什么?"第一个人有点不高兴,吼道"难道你看不出来我在砌砖吗?"女士对这个答案并不满意,接着问第二个人他在做什么.第二个人回答道,"我正在建造一堵砖墙."然后,他转向第一个人,说道:"嘿,你砌的砖已经超过墙高了.你得把最后一块砖拿下来."女士对这个答案还是不满意,她接着问第三个人他在做什么.第三个人抬头看着天空

如何将自己的电脑搭建成一个web服务器

问题描述 如何将自己的电脑搭建成一个web服务器 不用其他软件可以做到么,或者说能不能搭建一个简易的,能够连接外网的,单对单的简易服务器呢,只用代码实现行么 解决方案 看你怎么界定"其它软件".windows操作系统自带的iis算不算"其它软件",如果不算,用它就可以了. 但是无论什么软件,都不能跨越或者解决你的网络问题.如果你的网络没有公网ip,电信运营商封掉了80端口,那就没任何办法了. 解决方案二: 用tomcat 或者 xampp集成包, 具体的网上都有 解

界面-做一个web服务器的流程是如何呢

问题描述 做一个web服务器的流程是如何呢 水平比较低,有个在虚拟机Linux下运行的程序,要做成有界面的web服务器,要用什么软件怎样的流程做呢?主要想知道流程,实在是无从着手..... 解决方案 web服务器程序是现成的,你需要的只是做一个管理界面而已.看你懂多少了,用c++/qt就可以做一个简单的程序.如果还不会,就花钱雇人帮你开发吧. 解决方案二: 用lighthttp等库 返回html页面内容给浏览器显示

有一个WEB服务器,两个客户同时操作JSP页面,一个删除一条数据,一个正好查询这条数据,报错了,怎么解决啊,急!!

问题描述 有一个WEB服务器,两个客户同时操作JSP页面,一个删除一条数据,一个正好查询这条数据,报错了,怎么解决啊,急!! 解决方案 解决方案二:引用楼主duobiao的回复: 有一个WEB服务器,两个客户同时操作JSP页面,一个删除一条数据,一个正好查询这条数据,报错了,怎么解决啊,急!! ......怎么会出错呢难道你做什么都不判断么?解决方案三:报啥错?解决方案四:一句话问题!不知道你是用什么做的,操作数据库用的是什么,数据库用的是什么,反正要有的什么都没有!解决方案五:引用2楼swan

Erlang实现的一个Web服务器代码实例_Erlang

转贴一个简单的Web服务器: httpd.erl %% httpd.erl - MicroHttpd -module(httpd). -author("ninhenry@gmail.com"). -export([start/0,start/1,start/2,process/2]). -import(regexp,[split/2]). -define(defPort,8888). -define(docRoot,"public"). start() ->