Angular4-在线竞拍应用-与服务器通信

前端之家收集整理的这篇文章主要介绍了Angular4-在线竞拍应用-与服务器通信前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_404_0@创建web服务器

  • 使用Nodejs创建服务器
  • 使用Express创建restful的http服务
  • 监控服务器文件的变化
@H_404_0@用webstorm建立一个名为server的空项目

@H_404_0@在文件中,执行命令npm init -y

@H_404_0@执行cnpm i @types/node –save

@H_404_0@在server中新建一个tsconfig.json

{
  "compilerOptions": { "module": "commonjs","target": "es5","emitDecoratorMetadata": true,"experimentalDecorators": true,"outDir": "build","lib": ["es6"] },"exclude": [ "node_modules" ] }
@H_404_0@配置一下webstorm

@H_404_0@Settings,Languages & Frameworks,TypeScript,把Enable TypeScript Compiler前边的对勾打上。

@H_404_0@在server中建一个文件server,在里边新建一个hello_server.ts文件

import * as http from 'http'

const server=http.createServer(function (request,response) { response.end('Hello World\n'); }).listen(8888);
@H_404_0@执行node build/hello_server.js

@H_404_0@之后访问http://localhost:8888/

@H_404_0@就会看到页面显示Hello World

@H_404_0@执行cnpm install express –save 来安装express框架

@H_404_0@执行cnpm install @types/express –save

@H_404_0@在第二个server中新建一个auction_server.ts

import * as express from 'express';

const app=express();

app.get('/',(req,res)=>{ res.send("Hello Express"); }); app.get('/products',res)=>{ res.send("接收到商品查询请求"); }); const server=app.listen(8888,"localhost",()=>{ console.log("服务器已启动,地址是:http://localhost:8888"); });
@H_404_0@执行node build/auction_server.js

@H_404_0@执行cnpm install -g nodemon 可以改变文件后不用重启服务

@H_404_0@执行nodemon build/auction_server.js 来启动服务

@H_404_0@修改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,'这是第五个商品,是我在学习慕课网Angular入门实战时创建的',new Product(6,6.99,'这是第六个商品,是我在学习慕课网Angular入门实战时创建的',['电子产品'])
];

app.get('/',res)=>{ res.json(products); }); const server=app.listen(8888,()=>{ console.log("服务器已启动,地址是:http://localhost:8888"); });
@H_404_0@然后访问http://localhost:8888/products

@H_404_0@添加一个方法

app.get('/product/:id',res) => { res.json(products.find((product) => product.id == req.params.id)); });
@H_404_0@然后访问http://localhost:8888/product/3

Http通讯@H_79_301@ @H_404_0@新建一个项目client

@H_404_0@打开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,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,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,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>;
}
@H_404_0@http服务就是一个标准的TypeScript的类,跟我们自己写的服务是一样的。

get(url: string,options?: RequestOptionsArgs): Observable<Response>;
@H_404_0@get就是发get请求的,post就是发post请求的,put就是发put请求的。。。

@H_404_0@url就是发订单请求的 路径,这是必须的参数

@H_404_0@options是可选参数,

@H_404_0@每个方法都返回一个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;
}
@H_404_0@其中url,method,body可以由调用方法来决定

@H_404_0@一般只会用这个方法来传递请求头headers

@H_404_0@新建一个组件ng g component product

@H_404_0@修改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 ); } } 
@H_404_0@修改product.component.html

<p>
  商品信息
</p>
<ul>
  <li *ngFor="let product of products">
    {{product.title}}
  </li>
</ul>
@H_404_0@修改app.component.html

<app-product></app-product>
@H_404_0@在client下新建一个配置文件proxy.conf.json。当头路径为/api时,都转发为localhost:8888

{
  "/api":{ "target":"http://localhost:8888" } }
@H_404_0@修改package.json,让服务启动的时候加载proxy.conf.json文件

"start": "ng serve --proxy-config proxy.conf.json",
@H_404_0@把服务端的地址前面都加上/api

app.get('/api/products',app.get('/api/product/:id',
@H_404_0@启动服务,访问http://localhost:4200/,就可以看到商品的名称了。

@H_404_0@http请求的发送并不是由get方法触发的而是由subscribe触发的

@H_404_0@另一种通过管道的写法

@H_404_0@修改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() {

  }

}
@H_404_0@修改product.component.html

<p>
  商品信息
</p>
<ul>
  <li *ngFor="let product of products | async">
    {{product.title}}
  </li>
</ul>
@H_404_0@添加请求头

import {Component,OnInit} from '@angular/core';
import {Http,Headers} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/Rx';

@Component({
  selector: 'app-product',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通讯@H_79_301@ @H_404_0@http协议在同一时间是能是发送请求或者接收响应。不能同时进行。

@H_404_0@而websocket协议可以在发送请求的时候也可以接收数据。

@H_404_0@是一个长连接协议,不需要在每次发送或接收时建立连接,延迟更低

@H_404_0@不需要每次都携带一些连接相关的信息,因此传递的信息少。

@H_404_0@在server项目中安装ws相关的包cnpm install ws –save

@H_404_0@执行cnpm install @types/ws –save-dev

@H_404_0@websocket不是一个请求响应的协议。服务器和客户端都可以主动发送请求。

@H_404_0@修改server项目中的auction_server.ts

import {Server} from 'ws';

const wsServer = new Server({port: 8085});
wsServer.on('connection',websocket => {
    websocket.send("这个消息是服务器主动推送的");

});
@H_404_0@在机器的8085端口创建一个服务器,当有任何一个客户端连接到这个服务器的时候,给这个客户端推送一个消息。

@H_404_0@htt通信p是通过订阅http服务的get或post方法返回的流来处理服务器的响应数据

@H_404_0@但是Angular并没有提供一个类似http服务端的类来从websocket中产生一个流,所以要自己写一个服务来返回流。

@H_404_0@在client项目新生成一个服务ng g service shared/webSocket

@H_404_0@修改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);
  }

}
@H_404_0@新建一个组件ng g component webSocket

@H_404_0@修改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");
  }

}
@H_404_0@修改web-socket.component.html

<button (click)="sendMessageToServer()">向服务器发送数据</button>
@H_404_0@修改app.component.html

<app-product></app-product>
<app-web-socket></app-web-socket>
@H_404_0@修改app.module.ts

providers: [WebSocketService],
@H_404_0@修改server中的auction_server.ts

const wsServer = new Server({port: 8085});
wsServer.on('connection',websocket => {
    websocket.send("这个消息是服务器主动推送的");
    websocket.on("message",message=>{
        console.log("接受到消息:"+message)
    })
});
@H_404_0@之后访问http://localhost:4200/,查看浏览器的控制台会看到“这个消息是服务器主动推送的”。

@H_404_0@然后点击按钮,查看server项目的控制台会看到“接受到消息:Hello from client”

@H_404_0@现在这种情况是只有在客户端连接的时候服务器才会推送消息,如何在任何需要的时候推送消息呢?

@H_404_0@修改auction_server.ts,添加

setInterval(()=>{ if(wsServer.clients){ wsServer.clients.forEach(client=>{ client.send("这是定时推送"); }) } },2000);
@H_404_0@遍历每个客户端,每2秒给每个客户端推送消息

猜你在找的Angularjs相关文章