Angular4-在线竞拍应用-与服务器通信
来源:互联网 发布:对linux系统的认识 编辑:程序博客网 时间:2024/04/30 00:39
创建web服务器
- 使用Nodejs创建服务器
- 使用Express创建restful的http服务
- 监控服务器文件的变化
用webstorm建立一个名为server的空项目
在文件中,执行命令npm init -y
执行cnpm i @types/node –save
在server中新建一个tsconfig.json
{ "compilerOptions": { "module": "commonjs", "target": "es5", "emitDecoratorMetadata": true, "experimentalDecorators": true, "outDir": "build", "lib": ["es6"] }, "exclude": [ "node_modules" ]}
配置一下webstorm
Settings,Languages & Frameworks,TypeScript,把Enable TypeScript Compiler前边的对勾打上。
在server中建一个文件server,在里边新建一个hello_server.ts文件
import * as http from 'http'const server=http.createServer(function (request,response) { response.end('Hello World\n');}).listen(8888);
执行node build/hello_server.js
之后访问http://localhost:8888/
就会看到页面显示Hello World
执行cnpm install express –save 来安装express框架
执行cnpm install @types/express –save
在第二个server中新建一个auction_server.ts
import * as express from 'express';const app=express();app.get('/',(req,res)=>{ res.send("Hello Express");});app.get('/products',(req,res)=>{ res.send("接收到商品查询请求");});const server=app.listen(8888,"localhost",()=>{ console.log("服务器已启动,地址是:http://localhost:8888");});
执行node build/auction_server.js
执行cnpm install -g nodemon 可以改变文件后不用重启服务
执行nodemon build/auction_server.js 来启动服务
修改auction_server.ts
import * as express from 'express';const app=express();export class Product { constructor(public id: number, public title: string, public price: number, public rating: number, public desc: string, public categories: Array<string>) { }}const products:Product[]= [ new Product(1, '第一个商品', 1.99, 3.5, '这是第一个商品,是我在学习慕课网Angular入门实战时创建的', ['电子产品']), new Product(2, '第二个商品', 2.99, 2.5, '这是第二个商品,是我在学习慕课网Angular入门实战时创建的', ['电子产品', '硬件设备']), new Product(3, '第三个商品', 3.99, 4.5, '这是第三个商品,是我在学习慕课网Angular入门实战时创建的', ['电子产品']), new Product(4, '第四个商品', 4.99, 1.5, '这是第四个商品,是我在学习慕课网Angular入门实战时创建的', ['电子产品']), new Product(5, '第五个商品', 5.99, 3.5, '这是第五个商品,是我在学习慕课网Angular入门实战时创建的', ['电子产品']), new Product(6, '第五个商品', 6.99, 2.5, '这是第六个商品,是我在学习慕课网Angular入门实战时创建的', ['电子产品'])];app.get('/',(req,res)=>{ res.send("Hello Express");});app.get('/products',(req,res)=>{ res.json(products);});const server=app.listen(8888,"localhost",()=>{ console.log("服务器已启动,地址是:http://localhost:8888");});
然后访问http://localhost:8888/products
添加一个方法
app.get('/product/:id', (req, res) => { res.json(products.find((product) => product.id == req.params.id));});
然后访问http://localhost:8888/product/3
Http通讯
新建一个项目client
打开node_modules/@angular/http/src/http.d.ts
import { Observable } from 'rxjs/Observable';import { RequestOptions } from './base_request_options';import { ConnectionBackend, RequestOptionsArgs } from './interfaces';import { Request } from './static_request';import { Response } from './static_response';/** * Performs http requests using `XMLHttpRequest` as the default backend. * * `Http` is available as an injectable class, with methods to perform http requests. Calling * `request` returns an `Observable` which will emit a single {@link Response} when a * response is received. * * ### Example * * ```typescript * import {Http, HTTP_PROVIDERS} from '@angular/http'; * import 'rxjs/add/operator/map' * @Component({ * selector: 'http-app', * viewProviders: [HTTP_PROVIDERS], * templateUrl: 'people.html' * }) * class PeopleComponent { * constructor(http: Http) { * http.get('people.json') * // Call map on the response observable to get the parsed people object * .map(res => res.json()) * // Subscribe to the observable to get the parsed people object and attach it to the * // component * .subscribe(people => this.people = people); * } * } * ``` * * * ### Example * * ``` * http.get('people.json').subscribe((res:Response) => this.people = res.json()); * ``` * * The default construct used to perform requests, `XMLHttpRequest`, is abstracted as a "Backend" ( * {@link XHRBackend} in this case), which could be mocked with dependency injection by replacing * the {@link XHRBackend} provider, as in the following example: * * ### Example * * ```typescript * import {BaseRequestOptions, Http} from '@angular/http'; * import {MockBackend} from '@angular/http/testing'; * var injector = Injector.resolveAndCreate([ * BaseRequestOptions, * MockBackend, * {provide: Http, useFactory: * function(backend, defaultOptions) { * return new Http(backend, defaultOptions); * }, * deps: [MockBackend, BaseRequestOptions]} * ]); * var http = injector.get(Http); * http.get('request-from-mock-backend.json').subscribe((res:Response) => doSomething(res)); * ``` * * @experimental */export declare class Http { protected _backend: ConnectionBackend; protected _defaultOptions: RequestOptions; constructor(_backend: ConnectionBackend, _defaultOptions: RequestOptions); /** * Performs any type of http request. First argument is required, and can either be a url or * a {@link Request} instance. If the first argument is a url, an optional {@link RequestOptions} * object can be provided as the 2nd argument. The options object will be merged with the values * of {@link BaseRequestOptions} before performing the request. */ request(url: string | Request, options?: RequestOptionsArgs): Observable<Response>; /** * Performs a request with `get` http method. */ get(url: string, options?: RequestOptionsArgs): Observable<Response>; /** * Performs a request with `post` http method. */ post(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>; /** * Performs a request with `put` http method. */ put(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>; /** * Performs a request with `delete` http method. */ delete(url: string, options?: RequestOptionsArgs): Observable<Response>; /** * Performs a request with `patch` http method. */ patch(url: string, body: any, options?: RequestOptionsArgs): Observable<Response>; /** * Performs a request with `head` http method. */ head(url: string, options?: RequestOptionsArgs): Observable<Response>; /** * Performs a request with `options` http method. */ options(url: string, options?: RequestOptionsArgs): Observable<Response>;}/** * @experimental */export declare class Jsonp extends Http { constructor(backend: ConnectionBackend, defaultOptions: RequestOptions); /** * Performs any type of http request. First argument is required, and can either be a url or * a {@link Request} instance. If the first argument is a url, an optional {@link RequestOptions} * object can be provided as the 2nd argument. The options object will be merged with the values * of {@link BaseRequestOptions} before performing the request. * * @security Regular XHR is the safest alternative to JSONP for most applications, and is * supported by all current browsers. Because JSONP creates a `<script>` element with * contents retrieved from a remote source, attacker-controlled data introduced by an untrusted * source could expose your application to XSS risks. Data exposed by JSONP may also be * readable by malicious third-party websites. In addition, JSONP introduces potential risk for * future security issues (e.g. content sniffing). For more detail, see the * [Security Guide](http://g.co/ng/security). */ request(url: string | Request, options?: RequestOptionsArgs): Observable<Response>;}
http服务就是一个标准的TypeScript的类,跟我们自己写的服务是一样的。
get(url: string, options?: RequestOptionsArgs): Observable<Response>;
get就是发get请求的,post就是发post请求的,put就是发put请求的。。。
url就是发订单请求的 路径,这是必须的参数
options是可选参数,
每个方法都返回一个Observable,也就是可观测的流,流中的元素类型是Response,通过订阅这个流来获取服务端响应的数据,RequestOptionsArgs定义了一组与请求相关的参数
export interface RequestOptionsArgs { url?: string | null; method?: string | RequestMethod | null; /** @deprecated from 4.0.0. Use params instead. */ search?: string | URLSearchParams | { [key: string]: any | any[]; } | null; params?: string | URLSearchParams | { [key: string]: any | any[]; } | null; headers?: Headers | null; body?: any; withCredentials?: boolean | null; responseType?: ResponseContentType | null;}
其中url,method,body可以由调用的方法来决定
一般只会用这个方法来传递请求头headers
新建一个组件ng g component product
修改product.component.ts
import {Component, OnInit} from '@angular/core';import {Http} from '@angular/http';import {Observable} from 'rxjs/Observable';import 'rxjs/Rx';@Component({ selector: 'app-product', templateUrl: './product.component.html', styleUrls: ['./product.component.css']})export class ProductComponent implements OnInit { dataSource: Observable<any>;//用来接收http服务返回的流 products: Array<any> = []; constructor(private http: Http) { this.dataSource=this.http.get('/api/products') .map((res)=>res.json()); } ngOnInit() { this.dataSource.subscribe( (data)=>this.products=data ); }}
修改product.component.html
<p> 商品信息</p><ul> <li *ngFor="let product of products"> {{product.title}} </li></ul>
修改app.component.html
<app-product></app-product>
在client下新建一个配置文件proxy.conf.json。当头路径为/api时,都转发为localhost:8888
{ "/api":{ "target":"http://localhost:8888" }}
修改package.json,让服务启动的时候加载proxy.conf.json文件
"start": "ng serve --proxy-config proxy.conf.json",
把服务端的地址前面都加上/api
app.get('/api/products',app.get('/api/product/:id',
启动服务,访问http://localhost:4200/,就可以看到商品的名称了。
http请求的发送并不是由get方法触发的而是由subscribe触发的
另一种通过管道的写法
修改product.component.ts
export class ProductComponent implements OnInit { products: Observable<any>; constructor(private http: Http) { this.products=this.http.get('/api/products') .map((res)=>res.json()); } ngOnInit() { }}
修改product.component.html
<p> 商品信息</p><ul> <li *ngFor="let product of products | async"> {{product.title}} </li></ul>
添加请求头
import {Component, OnInit} from '@angular/core';import {Http,Headers} from '@angular/http';import {Observable} from 'rxjs/Observable';import 'rxjs/Rx';@Component({ selector: 'app-product', templateUrl: './product.component.html', styleUrls: ['./product.component.css']})export class ProductComponent implements OnInit { products: Observable<any>; constructor(private http: Http) { let myHeaders: Headers = new Headers(); myHeaders.append("Authorization", "Basic 123456") this.products = this.http.get('/api/products', {headers: myHeaders}) .map((res) => res.json()); } ngOnInit() { }}
WebSocket通讯
http协议在同一时间是能是发送请求或者接收响应。不能同时进行。
而websocket协议可以在发送请求的时候也可以接收数据。
是一个长连接协议,不需要在每次发送或接收时建立连接,延迟更低
不需要每次都携带一些连接相关的信息,因此传递的信息少。
在server项目中安装ws相关的包cnpm install ws –save
执行cnpm install @types/ws –save-dev
websocket不是一个请求响应的协议。服务器和客户端都可以主动发送请求。
修改server项目中的auction_server.ts
import {Server} from 'ws';const wsServer = new Server({port: 8085});wsServer.on('connection', websocket => { websocket.send("这个消息是服务器主动推送的");});
在机器的8085端口创建一个服务器,当有任何一个客户端连接到这个服务器的时候,给这个客户端推送一个消息。
htt通信p是通过订阅http服务的get或post方法返回的流来处理服务器的响应数据
但是Angular并没有提供一个类似http服务端的类来从websocket中产生一个流,所以要自己写一个服务来返回流。
在client项目新生成一个服务ng g service shared/webSocket
修改web-socket.service.ts
import {Injectable} from '@angular/core';import {Observable} from "rxjs";@Injectable()export class WebSocketService { ws: WebSocket; constructor() { } /** * 这个方法返回一个流,流中包括服务器推送的消息 * @param {string} url * @returns {Observable<any>} */ createObservableSocket(url: string): Observable<any> { //创建一个websocket对象,这个对象会根据传进去的url去连接指定的websocket服务器 this.ws = new WebSocket(url); return new Observable( observer => { this.ws.onmessage = (event) => observer.next(event.data); this.ws.onerror = (event) => observer.error(event); this.ws.onclose = (event) => observer.complete(); } ); } //向服务器发送一个消息 sendMessage(message: string) { this.ws.send(message); }}
新建一个组件ng g component webSocket
修改web-socket.component.ts
import {Component, OnInit} from '@angular/core';import {WebSocketService} from "../shared/web-socket.service";@Component({ selector: 'app-web-socket', templateUrl: './web-socket.component.html', styleUrls: ['./web-socket.component.css']})export class WebSocketComponent implements OnInit { constructor(private wsService: WebSocketService) { } ngOnInit() { this.wsService.createObservableSocket("ws://localhost:8085") .subscribe( data=>console.log(data), err=>console.log(err), ()=>console.log("流已经结束") ); } sendMessageToServer(){ this.wsService.sendMessage("Hello from client"); }}
修改web-socket.component.html
<button (click)="sendMessageToServer()">向服务器发送数据</button>
修改app.component.html
<app-product></app-product><app-web-socket></app-web-socket>
修改app.module.ts
providers: [WebSocketService],
修改server中的auction_server.ts
const wsServer = new Server({port: 8085});wsServer.on('connection', websocket => { websocket.send("这个消息是服务器主动推送的"); websocket.on("message",message=>{ console.log("接受到消息:"+message) })});
之后访问http://localhost:4200/,查看浏览器的控制台会看到“这个消息是服务器主动推送的”。
然后点击按钮,查看server项目的控制台会看到“接受到消息:Hello from client”
现在这种情况是只有在客户端连接的时候服务器才会推送消息,如何在任何需要的时候推送消息呢?
修改auction_server.ts,添加
setInterval(()=>{ if(wsServer.clients){ wsServer.clients.forEach(client=>{ client.send("这是定时推送"); }) } },2000);
遍历每个客户端,每2秒给每个客户端推送消息
- Angular4-在线竞拍应用-与服务器通信
- Angular4-在线竞拍应用-组件间通信
- Angular4-在线竞拍应用-路由
- Angular4-在线竞拍应用-管道
- Angular4-在线竞拍应用-项目结构分析
- Angular4-在线竞拍应用-项目启动过程
- Angular4-在线竞拍应用-开发组件
- Angular4-在线竞拍应用-依赖注入
- Angular4-在线竞拍应用-数据绑定
- Angular4-在线竞拍应用-响应式编程
- Angular4-在线竞拍应用-组件的生命周期
- Angular4-在线竞拍应用-ngContent指令
- Angular4-在线竞拍应用-开发环境的搭建
- Angular4-在线竞拍应用-引入第三方的库
- Angular4搭建在线可竞拍网站
- 在线竞拍系统-ajax轮询
- Angular 4.0_在线竞拍网站(3)_引入所需框架与类库
- Angular4关于组件与组件之间的通信
- 马化腾公开信:腾讯将推智慧零售解决方案丨用友前三季度财报营收增长24.4%【软件网每日新闻播报│第10-30期】
- 【2B研究】老板愿意CRM免费,但销售主管接受收费
- ASP.NET SignalR 2.0 入门指南
- MyBatis #{} 和 ${} 的区别
- 曹可爱之最可爱-Vue.js入门(十)组件1
- Angular4-在线竞拍应用-与服务器通信
- .NET:在ASPX、ASHX和MVC中使用IOC容器
- 国家互联网信息办公室公布《互联网新闻信息服务单位内容管理从业人员管理办法》【软件网每日新闻播报│第10-31期】
- 前端面试题(6)图片格式jpg,gif,png-8,png-24的区别,及其各自的使用场景
- Docker实战:使用Docker安装部署Gitlab
- 电阻桥(惠斯通电桥)的分析方法及用途
- 程序在内存中的分布
- 学习笔记TF053:循环神经网络,TensorFlow Model Zoo,强化学习,深度森林,深度学习艺术
- 计算机视觉