1.5、Web服务器

文章导读:本文讲解web服务的工作机制以及简单服务程序开发。为什么要学习web服务呢?首先,webrtc对安全性要求高,不允许直接从本地打开网页;其次,在浏览器中调用webrtc API 要求有SSL加密证书,即https;最后,webrtc的通信需要开发者自己开发信令服务程序,web服务可扩展为信令服务。基于上述三个重要原因,本节内容,手把手带大家开发一个web服务程序,已有基础的读者可以快速阅读。推荐阅读方式:理解+实操。

   本书目录 

   正文开始。

   一、web服务工作机制

   考虑到大部分前端读者,这里还是对web服务的工作机制做下简单描述,如果你已经非常熟悉web服务了,那么建议快速浏览或者直接跳到下一部分阅读。首先来看第一个问题:什么是Web服务?web服务就是web服务程序对外提供的数据服务。额(⊙o⊙)…,这种教科书式的定义估计你不喜欢,Me too。那就来讲一个案例吧。就比如银行里业务,常见的业务有存钱、取钱、开户、改密等。当我们去办理业务时,我们就是客户,柜台人员就是服务者;客户向服务者发送办理某种业务的请求(如同web请求),如发送取钱的请求,服务者首先要验证客户提交的资料是否合规,若不合规本次请求被停止,并反馈给客户(如同服务程序回应客户的web请求);如果合规则业务继续办理,同时也给客户反馈结果。虽然是同一个服务者,但是可以办理不同的业务(同web API),可以开户、存钱、取钱、改密码 等。在案例中,web服务就像是银行服务者提供的业务服务, web服务程序就是银行柜台的服务者(软件),银行大厅就是服务器(硬件),我们即将编写的服务程序就像是在“创造”一个服务者。好了,这些关键的概念讲解就到这里,接下来单独讲解最后一个关键概念——数据服务。

  数据服务,顾名思义就是和数据操作相关的服务,比如读取文章列表、读取某篇文章详情、新增一篇文章到服务器服务等。每一个服务就是一个业务,和在银行中存钱、取钱业务是一样的。web服务的数据服务提供方式就是对外开放URL地址,客户只需要通过URL就可以申请并办理相应的“业务”。还是上面的例子,我们来模拟这几条web数据服务。

  假设主机的地址是http://www.abc.com,针对上述这些数据服务,我们可以这样划分:①、http://www.abc.com/article/getArticleList 来表示读取文章列。在这里需要注意,URL的层级划分,一般用“/”来标识,至于这里为什么要用“/article/getArticleList”完全是开发者自定义,就我的个人习惯,觉得这种业务层级划分比较清晰,仅此而已。②、http://www.abc.com/article/getArticle表示读取某篇文章。③、http://www.abc.com/article/addArticle表示新增一篇文章到服务端业务。

   小结下。web服务器如同银行大厅,硬件,在计算机体系中表现为一台主机;web服务程序如图银行柜台的服务者,软件,在计算机体系中表现为一个程序;web服务如同银行的业务服务,由web服务程序提供, 一个web服务程序会提供很多个web服务,每个web服务对外的表现就是一个URL地址。

   第一部分的内容就讲到这里,建议你要完全理解,接下来是实操部分。

  二、编写web服务程序并运行

  理解到这里之后,接下来我们开始来设计这个服务端程序,使用到的编程语言是JavaScript(JS),所以我这里建议对读者的最基要求是:熟悉基本的JS语法,特别是es6语法。

  在大部分读者的眼中,JS就是一个简单的前端脚本语言,写写网页小特效还行,写服务端程序少见,没错, JS发源于前端。所有健全的浏览器中都内置了JS的执行引擎,负责解析和运行JS代码,其中,最厉害的要数谷歌的V8引擎。国外一位名叫Ryan Dahl的“大神”,把V8引擎单独抽出来,封装成了一个独立的程序——Node.js。Node.js使得之前只在浏览器中工作的V8引擎不再只是浏览器的一部分。Node.js 并不是一门新的语言,而是一个JS的运行环境,它使得JS可以如同java、python、php等语言一样可以编写和运行服务端程序。接下来,我们来安装Node.js程序,这里以Windows 系统为例,其他系统的读者自行查阅资料。Node.js安装程序可以打开其官网——https://nodejs.org/en/ 下载,如下图1.5.1所示。读者自行选择对应的版本下载即可,我这里选择了"12.x"的版本,由于安装的步骤比较简单,这里不再赘述,安装时建议可以使用默认的配置选项,一路“next”即可。

 

 

图1.5.1 (Node.js 官网)

 

   Node.js环境安装完成以后,接下来验证下是否安装成功,打开cmd命令行工具,执行 “node -v” 命令。若如下图1.5.2所示,即表示安装成功。

图 1.5.2 (Node.js 安装结果测试)

 

 

    至此,Nodejs环境安装成功,接下来再介绍Node.js中非常关键的包管理工具——npm。这里所谓的包可以理解为Node.js 的第三方库,Node.js 自身内置了很多的包,但是远远不够用,很多第三方的开发者或者团队就自行开发了各种包,通过npm工具可以非常方便的管理这些包。本节内容是带领读者搭建一个web服务程序,所用到的包是express,接下来我们就来实战安装、查看、更新、卸载这个库/包。

   新建一个目录“webrtc”(文件夹名可自行定义)作为这个项目总目录,如下图1.5.2所示。

  

图 1.5.2 (项目总目录)

 进入“webrtc目录”,并且在该目录中打开命令行工具,打开的方式为“Shift+鼠标右键”调出菜单,选择“在此处打开Powershell窗口(S)”(有些电脑是“在此处打开命令窗口(W)”,命令窗口如下图1.5.3所示。

 

图 1.5.3 

 

 

在这里,我的电脑默认的命令行工具是Powershell,有些读者是CMD,但操作的步骤都是一样的(Powershell 可以看做是CMD的升级版,老版本的系统都是CMD这主要的命令行工具)。如果不用上述的快捷方式,还可以这么操作,首先任意方式打开命令行工具,然后通过命令定位到项目目录即可;具体操作为:输入e:,再输入回车, 先定位到项目目录所在的磁盘(我的项目目录在e盘,所以输入e:);接下来再定位到具体的目录,输入cd a\b\c,并键入回车即可定位到指定目录,注意,这里的a\b\c是我的目录结构,你需要根据实际情况来改。综合考虑,我建议用第一种。

  命令工具搞定了,接下来安装express 包, 在安装之前,我们还需要做两个配置,第一、修改包仓库源地址,npm默认的包仓库源地址是在国外,在国内安装包的速度较慢, 所以这里推荐使用淘宝的源仓库地址,修改的命令为:npm config set registry https://registry.npm.taobao.org/,npm官网源仓库地址为https://registry.npmjs.org/,淘宝的仓库号称10分钟同步一次官方的包,为国内的开发者提供了便利,在这里给淘宝点赞。需要注意的是,虽然我们使用淘宝仓库在读取包时很快,但如果我们要自己发布包, 则需要把源地址改回官网源仓库地址,即npm config set registry https://registry.npmjs.org/,因为淘宝的源仓库只可读。源仓库地址修改一次就行了,后续的操作都生效。第二、在项目目录中创建配置文件,创建的方式非常简单,在当前目录的命令工具中输入npm init,回车即可进入配置文件创建向导,我的习惯是一路回车,直到最后提示确认信息是否OK时再输入yes回车即可,在配置创建向导中,填写的信息比较简单,都是一些项目的基本信息,如项目名称、项目作者、项目描述等,在生成的配置文件中也可以改。创建过程如下图1.5.4 所示。

 

 

 

图1.5.4 (配置文件创建向导) 

配置文件如下图1.5.5所示。

图 1.5.5 配置文件

 

 

 

配置文件是json文件格式,使用编辑器打开,各个字段如下图1.5.6所示。

 

 

 图 1.5.6(配置文件基础信息)

解释下这些字段的含义,name为项目名;version为当前项目的版本号,开发者自定义; description为本项目的描述信息;main为项目的入口文件(开发者自定义);scripts是本项目的一些快捷命令的定义,如上图中定义了“test”命令,我们在本目录下可以通过 npm run test 来间接的执行 “echo \"Error: no test specified\" && exit 1”这个命令,在实际开发中非常实用,后面会讲到;author为项目作者;license为项目的许可类型。 这些都是基本的配置信息,还有其他的配置信息,用到时再说明。

  上面的两步配置完之后,现在可以正式安装express包了,输入npm install express --save(学习到npm的第一个命令),并回车即可开始安装,安装的进度以及结果如下图1.5.7所示。

   

图  1.5.7

稍等片刻,express的包就被下载并安装到当前目录下了。如下图1.5.8所示。

  图 1.5.8

 此时,项目下多了一个文件夹——node_modules和一个package-lock.json(关于这个文件的作用,点击这里查看),node_modules文件夹是自动生成的,即用于存放本项目所有的依赖包的代码,例如本项目的一个依赖包——express的代码就被下载到这个文件夹下,随着项目的功能越来越完善,依赖包越来越多,全都被存放到这个目录中。这里解释下安装包时为什么加 --save 参数,该参数表示保存这个包的名字到配置文件package.json中, 如果没有--save,express的包名不会写入配置文件,我们在发布项目或者拷贝项目给别人的时候,node_modules文件夹是不拷贝的,别人拿到我们的项目之后,只需要在当前目录下执行npm install 命令即可安装package.json中记录的所有依赖包 (学习到npm的第二个命令),npm会自动读取package.json文件中的依赖包信息——dependencies字段内容并完成安装。

  现在打开package.json文件,如下图1.5.9所示。

 

 

 图 1.5.9 

安装完express包之后,在配置中多了一项,dependencies表示的是本项目所依赖的包,"express": "^4.17.1"表示express包的版本至少是4.17.1及以上。卸载包npm uninstall express , 更新包 npm update express,npm list 查看已安装包列表 。这几个命令大家自行尝试了。

  至此,我们已经做了这些前期的工作:安装Node.js环境,学习了npm的基本使用,完成了express 包的安装。这里解释下express这个包的作用?express是一个提供了开发web服务程序所需功能的包,在接下来的编码工作中,将会依赖express来构建web服务程序。编写代码吧,新建一个index.js文件,如下图1.5.10所示。

 

图1.5.10

 

 使用编辑器打开index.js文件,首先导入express包,并且通过express实例化一个应用对象——app。代码如下。

const express = require("express");
const app= express(); // 实例化一个应用对象

 

启动web服务需要监听一个端口,端口的概念就像是计算机与外界通信窗口,一个服务程序的运行需要向操作系统申请监听一个端口才可以提供服务。一个端口只能被一个程序监听,如果端口被占用了,程序将无法执行, 这里我们选择使用http服务的默认端口80,代码如下。

1 app.listen(80, ()=>{
2     console.log('Server is running at http://localhost')
3 })

 

 完整代码如下。

const express = require("express");
const app = express();
app.listen(80,()=>{
  console.log('Server is running at http://localhost')
})

 到此,一个简单的web服务程序已经建立起来,现在运行下这个程序,运行的方法:在当前目录下执行:node index.js 即可。操作系统考虑到安全问题,首次运行可能会弹出安全警告,如下图1.5.11所示,点击“允许访问”即可。

 

 

图 1.5.11

 运行的效果如下图1.5.12,到这里web服务程序已经运行成功了。

图 1.5.12 

如果你电脑的80端口已经被其他程序占用,那么程序将会报错,如下图1.5.13所示。

 

图 1.5.13 (端口被占用)

 

 

 出现这种情况,要么停掉占用该端口的程序,要么自己换一个端口监听。 如果你的服务程序启动成功,接下来就可以访问了web服务了,访问的网址为http://localhost,如下图1.5.14所示。这里可能会存在疑问,比如为什么通过http://localhost来访问?这种常识问题,建议问搜索引擎,这里不再赘述。

 

图 1.5.14

 

 如上图所示,访问服务得到结果是 “Cannot GET /”,说明的服务程序无法识别这个请求——“/”(因为最后一个/会被省略掉,所以我们只看到http://localhost,完整的路径应该是http://localhost/ ),原因是服务器现在还不能处理任何业务,于是我们给它加点业务吧。代码如下。

const express = require("express");
const app = express();

//这里注册一个服务业务
app.get("/article/getArticleList",(req,res)=>{
    res.send("getArticleList");//给访问者返回一个字符串
})

app.listen(80,()=>{
  console.log('Server is running at http://localhost')
})

再次访问得到如下结果,如图1.5.15。

  

 

图 1.5.15

这里解释下这段业务代码的含义,“app.get” 说明Web服务处理的是“GET”请求;“/article/getArticleList”是某一个业务的标识;匿名函数“

(req,res)=>{
res.send("getArticleList");
}

”表示的是业务的处理函数,“res.send("getArticleList");”表示向来访的客户返回一个“getArticleList”字符串。

 

在Node.js中,简单的几行代码即可实现web服务程序,有没有感觉很简单。接下来还有一个重要的问题,即是静态文件,上述这个web API—— /article/getArticleList,返回的数据是程序动态生成,但类似图片、文本、网页文件等这类文件不好动态生成,这类文件都是确定好的文件,在express中有单独有处理静态文件的方法,接下来看看如何处理。新增一行代码就够了。

app.use('/static', express.static('public'));//  “/static” 是访问静态文件路径的前缀(可自定义),public是存放静态文件的目录(可自定义),public目录需在当前项目目录下

最终的代码如下。

const express = require("express");
const app = express();
app.use('/static', express.static('public'));// 静态文件处理方法
//这里注册一个服务业务
app.get("/article/getArticleList",(req,res)=>{
    res.send("getArticleList");
})
app.listen(80,()=>{
  console.log('Server is running at http://localhost')
})

 

 为了体验express管理静态文件,我新建了一个public目录(public和代码中的一致) ,目录结构如下图1.5.16。

 

图1.5.16 

 

 接下来在public中放置一些静态文件,如下图1.5.17所示。

 

 

 

图1.5.17 

 然后就可以在浏览器中访问这些静态文件。如下图1.5.18所示。

              

图1.5.18

 

  好了,舒一口气,关于web服务程的相关内容已经讲完,我建议你务必参照内容,自己完成一个web服务程序,且要运行起来。

  最后,总结。 本文首先通过银行业务办理的例子讲解了web服务器程序的工作机制,并引出了这几个概念:Web服务器、Web服务器程序、web服务、数据服务;紧接着介绍了Node.js的相关技术,如包管理工具npm的基本使用,创建Node.js项目的步骤;最后编码实现了一个web服务程序。

  本文内容就到这里,祝学习愉快。

   最后,附上本书指定交流微信公众号——“晨叔周刊”,一起讨论吧。

上一篇:1.4、WebRTC 架构

下一篇:1.6、本章小结

  

posted on 2020-02-28 20:39  Rajan  阅读(849)  评论(0编辑  收藏  举报
扫码和作者预约吧