创建web服务器
使用express搭建
- 通过npm init -y 命令会创建一个含有默认配置的 package.json的文件
- 为了让nodejs支持typescript 使用命令:npm i @types/node —save
-
创建tsconfig.json文件:
{ "compilerOptions": { "target": "es5", "module": "commonjs", "emitDecoratorMetadata": true, "experimentalDecorators": true, "outDir": "build", "lib": ["es6"] }, "exclude": ["node_modules"] }
- 然后安装express相关插件 npm install express —save
- 同样需要让他支持typescript npm i @types/express —save
- 编译过后(我使用的是VS code, 通过run task,进行编译), 通过 node build/编译出来的文件。执行就行。执行命令为node build/auction_server.js
- 如果需要热部署可以安装nodemon 命令为 npm install nodemon -g
下面贴出服务器端代码的样例:
//引入Express包的相关引用
import * as express from 'express'
//引入WebSocket的包
import {Server} from 'ws'
import bodyParser = require('body-parser');
/**
* 通过express对象,拿到具体属性
*/
const app = express();
//如果需要post请求,一定要加入这段代码,否则会request body会是undefined
app.use(bodyParser.json());
/**
* 这个类作为一个 product的实体类,被用来承接从后台发过来的数据。
*/
// tslint:disable-next-line: class-name
export class productModel {
constructor(
public id: number,
public title: string,
public price: number,
public rating: number,
public desc: string,
public categories: Array<string>
) {}
}
const products: productModel[] = [
new productModel(1,"title1",1,1,"Description1,Description1,Description1,Description1",["图书","电子书"]),
new productModel(2,"title2",2,2,"Description2,Description2,Description2,Description2",["手机","电子书"]),
new productModel(3,"title2",2,3,"Description3,Description3,Description3,Description3",["pad","笔记本"]),
new productModel(4,"title2",2,4,"Description4,Description4,Description4,Description4",["手机","笔记本"]),
new productModel(5,"title2",2,5,"Description5,Description4,Description4,Description4",["笔记本","图书"]),
new productModel(6,"title6",6,5,"Description6,Description6,Description6,Description6",["pad","手机"])
];
// tslint:disable-next-line: class-name
export class commentModel {
constructor(
public id: number,
public productId: number,
public title: string,
public rating: number,
public desc: string
) {}
}
const comments: Array<commentModel> = [
// tslint:disable-next-line: no-use-before-declare
new commentModel(1, 1, "title1", 1, "Comment1"),
// tslint:disable-next-line: no-use-before-declare
new commentModel(2, 1, "title2", 2, "Comment2"),
// tslint:disable-next-line: no-use-before-declare
new commentModel(3, 1, "title3", 3, "Comment3"),
];
/**
* 定义一个get请求的API
*/
app.get('/', (request, response) => {
response.send('Hello Express');
});
/**
* 定义一个get请求的API,为了获取商品信息。
*/
app.get('/api/product', (request, response) => {
response.json(products);
});
app.get('/api/product/:id', (request, response) => {
response.json(products.find((product) => product.id == request.params.id));
});
app.get('/api/comments', (request, response) => {
response.json(comments);
});
app.get('/api/comments/:productId', (request, response) => {
response.json(comments.filter(comment => comment.productId == request.params.productId));
});
app.post('/api/products/condition', (req, res) => {
console.log(req.body);
res.json(products);
});
/**
* 让服务器监听8000端口,并且开启服务。
*/
app.listen(8000, 'localhost', () => {
console.log('node js 服务器已经启动!!');
});
通过express-generator搭建
- 通过命令安装 npm install express-generator —save -g
- 下载好后,直接express 项目名 即可。
- 然后通过命令 npm install 安装相应的包
- 如果想运行 通过命令 npm start。
Http通讯
要想使用angular的http请求,请按照如下几步操作来做:
-
在app.module.ts imports中添加上HttpClientModule模块
import { HttpClientModule } from '@angular/common/http';
-
在需要使用的地方,引入Obserable,和HttpClient包
import { Observable } from 'rxjs'; import { HttpClient } from '@angular/common/http';
-
将HttpClient依赖注入进来,然后定义我们想要的请求:
constructor(private http: HttpClient) { this.dataObservable = http.get('api/product'); }
-
然后在想要发送请求的地方,直接订阅我们刚刚定义的那个请求:
this.dataObservable.subscribe((response) => { console.log(response); this.products = response; });
️请求是在这里subscribe的时候,才会真正的发送出去。
下面给出完整的代码:
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
private dataObservable: Observable<any>;
private products: Array<any>;
constructor(private http: HttpClient) {
this.dataObservable = http.get('api/product');
}
ngOnInit() {
this.dataObservable.subscribe((response) => {
console.log(response);
this.products = response;
});
}
}
然后需要着重说一下的是,这样虽然说定义好了,但是请求还是发不出去的,因为我们要访问的不可能是在当面的这个项目中的,一定是开在了别的某台机器上的某个项目里。
那这应该怎么办呢?
我们需要定一个文件,告诉angular这些情况,我们定义一个proxy.config.json,文件内容如下:
{
"/api": {
"target": "http://localhost:8000"
}
}
这段代码的意思是告诉angular如果是api前缀的URL,我们应该去本地的8000端口中去寻找。
最后将package.json中的 scripts中的start指令改为如下的命令即可:
"start": "ng serve --proxy-config proxy.conf.json"
WebSocket通讯
webSocket协议
传统的Http协议,只能是在发送请求状态和接收响应状态相互交换。而webSocket可以在一个连接点进行交换数据。
webSocket是一个长连接。
webSocket协议相对于http协议携带的数据更少。
安装webSocket在nodejs中
通过命令:
npm install ws --save
npm install @types/ws --save
服务端websocket
websocket的服务器端和Http服务器的搭建特别类似:
-
引入WebSocket包
//引入WebSocket的包 import {Server} from 'ws'
-
监听WebSocket连接时间,然后作出对应的处理
webSocket.on('connection', websocket => { //从服务器端推送一个消息返回给客户端 websocket.send("客户端连接后,响应给客户端的消息"); //接收从客户端端发来的消息 websocket.on('message', message => console.log(message)); });
-
有的时候我们也有服务器端在一段时间间隔内,不断向客户端推送的需要:
** * 定时向客户端推送消息,间隔为三秒 */ setInterval(function(){ if (webSocket.clients) { webSocket.clients.forEach(client => { client.send('定时发送消息'); }); } }, 3000);
客户端websocket
封装两个方法用于以后的使用:
首先定义一个变量 ws: WebSocket;
-
建立与服务器端的连接
/** * 这个方法用于当我们发送一个连接的方法 * @param url */ createObserableWebSocket(url: string): Observable<any> { this.ws = new WebSocket(url); return new Observable( obserer => { //当有消息发送过来时候的一个监听。 this.ws.onmessage = (event) => obserer.next(event.data); //当有错误的时候一个监听。 this.ws.onerror = (event) => obserer.error(event); //当结束的时候一个监听。 this.ws.onclose = (event) => obserer.complete(); }); }
-
向服务器端推送消息
/** * 通过websocket发送消息 */ sendMessage(msg: string) { this.ws.send(msg); }
然后就可以通过使用这两个方法进行与websocket服务端的通信。
在需要建立websocket的地方写如下的代码,一般会写在ngOnInit方法中,也就是说在组件刚开始创建的时候,就会建立连接:
this.wsService.createObserableWebSocket('ws://localhost:8085')
.subscribe(
data => console.log(data),
error => console.log(error),
() => console.log('连接完成')
);
如果需要发送消息,可以写如下代码:
this.wsService.sendMessage('从客户端发送的消息');