一 Web服務(wù)器
1. Web服務(wù)器的功能
1). 接收http請(qǐng)求 ( GET, POST) restful(DELETE, PUT, PATCH)
2). 處理HTTP請(qǐng)求 (自己處理, 或請(qǐng)求別的程序處理)
做出響應(yīng) (返回頁(yè)面, 文件, 各類(lèi)數(shù)據(jù)等)
2. 常見(jiàn)的Web架構(gòu)
1). Nginx/Apache: 負(fù)責(zé)接受HTTP請(qǐng)求, 確定誰(shuí)來(lái)處理請(qǐng)求, 并返回請(qǐng)求的結(jié)果
- php-fpm/php模塊 : 處理分配給自己的請(qǐng)求, 并將處理結(jié)果返回給分配者
3. 常見(jiàn)的請(qǐng)求種類(lèi)
1). 請(qǐng)求文件: 包括靜態(tài)文件(網(wǎng)頁(yè), 圖片嗎前端JavaScript文件, css文件...), 及由程序處理得到的文件
2). 完成指定的操作: 如登錄, 獲取特定數(shù)據(jù)等
二 Node.js 的Web服務(wù)器
特性:
1). 不依賴(lài)其他特性的Web服務(wù)軟件 (如 Apache, Nginx, IIS...)
2). Node.js代碼處理請(qǐng)求的邏輯
3). Node.js代碼負(fù)責(zé)Web服務(wù)器的各種 "配置"
1. 使用Node.js的核心模塊http搭建Web服務(wù)器
1). 創(chuàng)建web.js
// web.js
// 引入http模塊
var http = require('http')
//設(shè)置請(qǐng)求監(jiān)聽(tīng)函數(shù)
/**
* param req: 請(qǐng)求信息
* param res: 響應(yīng)信息
*/
var requestHandler = function (req, res) {
res.end('hello');
}
//創(chuàng)建服務(wù)器
var web = http.createServer(requestHandler)
//設(shè)置監(jiān)聽(tīng)端口號(hào)
web.listen(7878)
console.log('http running on http://localhost:7878')
2). $ node web.js
3).測(cè)試服務(wù)器是否搭建成功
方法一: 新建一個(gè)終端窗口運(yùn)行命令
$ curl http://localhost:7878
方法二: 瀏覽器中打開(kāi)地址
http://localhost:7878
2. 使用express搭建服務(wù)器
1). 安裝express庫(kù)
$ cd express.js
$ npm install express
2). 新建文件express.js
//引入express的模塊
var express = require('express');
//創(chuàng)建實(shí)例
var app = express();
//靜態(tài)文件
// http://exapmle.com/static.file
app.use(express.static('./public'));
app.get('/', function (req, res, next) {
res.end('hello \n')
next();
})
//設(shè)定監(jiān)聽(tīng)端口, 和回調(diào)函數(shù)
app.listen(7878, function afterListen() {
console.log('express running on http://localhost:7878');
});
3). 測(cè)試服務(wù)器是否創(chuàng)建成功
方法一: 新建一個(gè)終端窗口運(yùn)行命令
$ curl http://localhost:7878
方法二: 瀏覽器中打開(kāi)地址
http://localhost:7878
3. 搭建TCP服務(wù)器
1). 使用net模塊創(chuàng)建TCP服務(wù)器
2). 使用telnet鏈接TCP服務(wù)器 - 使用telnet進(jìn)行測(cè)試
- 安裝telnet
$ brew install telnet- 測(cè)試鏈接
$ telnet localhost 18001 //telnet 地址 端口號(hào)- 直接輸入內(nèi)容回車(chē)即可發(fā)送數(shù)據(jù)
buffer是用來(lái)處理二進(jìn)制和非unicode數(shù)據(jù)的類(lèi), tcp通訊中傳輸?shù)脑紨?shù)據(jù), 在nodejs中便是使用buffer的實(shí)例來(lái)進(jìn)行封裝的- 查看當(dāng)前系統(tǒng)使用的端口號(hào)
1) netstat 命令 grep篩選結(jié)果
lsof -i :18001
- 查看telnet的進(jìn)程 殺死進(jìn)程, 查看鏈接關(guān)閉的效果
// tcp.js
const PORT = 18001;
const HOST = '127.0.0.1';
//導(dǎo)入核心模塊
var net = require('net');
//監(jiān)聽(tīng)函數(shù)
var clientHandler = function (socket) {
console.log('someone connected');
//服務(wù)器端收到客戶端發(fā)送的數(shù)據(jù)
socket.on('data', function dataHandler(data) {
console.log(socket.remoteAddress, socket.remotePort, 'send', data.toString())
//服務(wù)器端向客戶端發(fā)送數(shù)據(jù)
socket.write('server received \n')
});
//鏈接斷開(kāi)
socket.on('close', function () {
console.log(socket.remoteAddress, socket.remotePort, 'connect close')
})
}
//創(chuàng)建服務(wù)器
var app = net.createServer(clientHandler);
app.listen(PORT, HOST);
console.log('TCP server running on tcp://', HOST, ':', PORT);
- 使用net創(chuàng)建TCP客戶端
// tcpClient.js
var net = require('net');
const HOST = '127.0.0.1';
const PORT = 18001;
var tcpClient = net.Socket();
tcpClient.connect(PORT, HOST, function () {
console.log('connect success');
tcpClient.write('this is tcp client by Node.js');
});
//接受服務(wù)器端的數(shù)據(jù)
tcpClient.on('data', function (data) {
console.log('receive: ', data.toString())
})
三. express
1. 使用express創(chuàng)建路由的三種方法
1) . path
//path 方法
app.get('/', function (req, res, next) {
res.send('express hello')
res.end(' hello\n')
next();
})
2). Router
var Router = express.Router();
/**
* http:/example.com/post/add
* http:/example.com/post/list
*/
Router.get('/add', function (req, res) {
res.end('Router add\n' );
})
Router.get('/list', function (req, res) {
res.end('Router list\n' );
})
app.use('/post', Router)
3). route
//指定不同方法下的不同的處理, 如post請(qǐng)求和get請(qǐng)求執(zhí)行的操作
//http://example.com/article
app.route('/article')
.get(function (req, res) {
res.end('route /article get \n')
})
.post(function (req, res) {
res.end('route /article post\n')
})
命令行發(fā)起post請(qǐng)求和get請(qǐng)求
//get請(qǐng)求
curl -X GET http://localhost:7878
//post請(qǐng)求
$ curl -X POST http://localhost:7878
2. 指定參數(shù)名
//http://example.com/news/123
app.param('newsId', function(res, req, next, newsId) {
req.newId = newsId;//將newId賦值給請(qǐng)求參數(shù)
next();//請(qǐng)求完執(zhí)行的函數(shù)
})
app.get('/news/:newsId', function (req, res) {
console.log(req.params)
res.end('newId: ' + req.params.newsId + '\n');
})
3. 中間件
Connect: Node.js 的中間件架構(gòu)
分層處理
每層實(shí)現(xiàn)一個(gè)功能
以打印日志中間件 morgan 為例
1.安裝morgan
$ npm install morgan
var morgan = require('morgan'); //打印日志
//中間件
app.use(morgan());
4. 自動(dòng)生成 express應(yīng)用模板
express生成工具, 直接生成express應(yīng)用模板
全局 安裝 express-generator
express expressHello/
vim package.json 查看執(zhí)行目錄 /bin/www.js
node bin/www
$ curl http://localhost:3000 默認(rèn)端口號(hào)實(shí)3000, 鏈接服務(wù)器測(cè)試
5. express的完整代碼
//引入express的模塊
var express = require('express');
var morgan = require('morgan'); //打印日志
//創(chuàng)建實(shí)例
var app = express();
//中間件
app.use(morgan());
//靜態(tài)文件
app.use(express.static('./public'));
//path 方法
app.get('/', function (req, res, next) {
res.send('express hello \n');
next();
});
//Router 方法
var Router = express.Router();
/**
* http:/example.com/post/add
* http:/example.com/post/list
*/
Router.get('/add', function (req, res) {
res.end('Router add\n' );
});
Router.get('/list', function (req, res) {
res.end('Router list\n' );
});
app.use('/post', Router);
//route 方法
//指定不同方法下的不同的處理, 如post請(qǐng)求和get請(qǐng)求執(zhí)行的操作
app.route('/article')
.get(function (req, res) {
res.end('route /article get \n')
})
.post(function (req, res) {
res.end('route /article post\n')
});
//http://example.com/news/123
//指定參數(shù)名
app.param('newsId', function(res, req, next, newsId) {
req.newsId = newsId;//將newId賦值給請(qǐng)求參數(shù)
next();//請(qǐng)求完執(zhí)行的函數(shù)
});
app.get('/news/:newsId', function (req, res) {
console.log(req.params);
res.end('newsId: ' + req.params.newsId + '\n');
});
//設(shè)定監(jiān)聽(tīng)端口, 和回調(diào)函數(shù)
app.listen(7878, function afterListen() {
console.log('express running on http://localhost:7878');
});