好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

angular5 websocket 商品价格 关注商品价格 在线商品竞拍

项目简介描述:模拟在在线商品竞拍,单击关注某个商品时,可以在商品详情页上看到实时的看到的别人竞拍的商品价格,模拟从后端实时的获取数据,当

单击取消按钮时,客户端即取消对服务器端的返回的数据的订阅,并关闭数据流。

项目流程图:

 

项目步骤:

1. 对点击关注按钮进行编码:

 1   //   模板代码 
 2  <div class="thumbnail">
 3    <button class="btn btn-default btn-lg" [class.active]="isWatched" (click)=\'watchProduct()\'>
 4      {{isWatched ? \'取消关注\':\'关注\' }}
  5    </button>
 6    <label>最新出价: {{currentBid | number: \'.2-2\'}}元</label>
 7  </div>

2. 模板中的ts属性的添加:

 //   关注参数 
  public isWatched: boolean  =  false ;  //   是否关注,默认是false,即为没有关注某个商品 
  public currentBid: number;  //   当前商品的价格 

   //   保存这个流 
  public subscription: Subscription;  //   当订阅一个流时的返回值,使用它可以取消对某个流的订阅 

 //   注入WebsocketService, 支持websocket协议,支持双向的通信,即客户端和服务器能同时回复和发送数据 
   //   服务需要注入器,此例中的引入的WebsocketService时,可以在constructor快速的实现注入,即可以使用 
  constructor(private productService: ProductService, private routeInfo: ActivatedRoute, private wsService: WebsocketService) { }

3. 作为中介媒体的服务来成为WebSocket的服务的创建流,发送消息的函数:

 //   常见WebSocket对象 
 public ws: Websocket;

    //   通过url来创建websocket流, 返回可观测的流 
  createObservableSocket(url: string, id: number): Observable<any>  {
      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();  //   当关闭时,可观察对象的完毕 
         this .ws.onopen = (event) =>  this .sendMessage({productId: id});  //   当ws打开时,即通过函数sendMessage发送数据 
         return  () =>  this .ws.close();  //   这个匿名函数取消订阅的方法的时候调用,关闭WebSocket, 否则的话,容易造成内存的泄露; 
       }
    )
  }

    //   通过创建的ws对象,来发送数据,发送的数据的格式是字符串的格式 
   sendMessage(message: any) {
      this .ws.send(JSON.stringify(message));  //   穿过来的参数是对象,但是send消息的格式是字符串格式的; 
  }

4. 在服务器中实现对productId的存储:

const Server = require(\'ws\').Server;  //   后端创建ws服务器  
//   Map中存在的是:每一个客户端关注的商品的id的数组,因为每一个客户端可以关注多个商品; 
const subscriptions =  new  Map<any, number[]> ();

const wsServer  =  new  Server({port: 8090 });

wsServer.on( \'connection\', (websocket) =>  {
  websocket.on( \'message\', (message) =>  {
        //   当客户端有信息传递时,即服务器端接收,由于这个客户端传递个是JSON.stringify({productId:id});所以在接到数据时,使用 
       //   JSON.parse(message);    
      let messageObj =  JSON.parse(message);
        //   key值是连接到服务端的客户端,当subscripitons.get(websocket)的值为undefined,则赋值为空数组;    
      let productIds = subscriptions.get(websocket) ||  []; 
        //   将新的商品的Id放到值的数组中;将已有的和新建的id组合在一起; 
      subscriptions.set(websocket, [...productIds, messageObj.productId]);  //   [...productIds]: 扩展运算符   
   })  
}) 

  1   //   实现消息向客户端的定时的推送 
  2   //   模拟数据的更新 
  3  setInterval( function  () {
   4       //   随机生成每个商品的最新的商品的价格 
  5      products.forEach((product) =>  {
   6        let currentBid = currentBids.get(product.id) ||  product.price;  
   7        let newBid = currentBid + Math.random() * 5 ;
   8         currentBids.set(product.id, newBid);           
   9       })
  10       //   循环每一个客户端, 推送每一个客户端关注的商品的价格 
 11      subscriptions.forEach((productIds: number[], ws) =>  {
  12           //   返回的数据的格式是:[{productId:xxx,bid: xxx},{},{}],对应是每个被关注的商品的最新的报价 
 13          //   *** 防止页面刷新报错; 
 14           if  (ws.readyState === 1 ) {
  15           //      通过映射将pid组成{productId: pid, bid: currentBid.get(pid)} 
 16              let newBids = productIds.map(pid =>  ({
  17                   productId: pid,
  18                   bid: currentBids.get(pid)
  19               }));
  20               //   发送的数据 
 21               ws.send(JSON.stringify(newBids));
  22          }  else   {
  23              subscriptions. delete (ws);  //   删除已经关闭的客户端 
 24           }
  25          //   这之后,然后在客户端订阅这个流; 
 26       });
  27  }, 2000);

5. 客户端对服务器的流的接收(关注)和取消(取消关注):

  1   watchProduct() {
   2       //   服务器返回的流的订阅 
  3       if  ( this  .subscription) {
   4         //    取消对流的订阅, 并对subscription赋值为null; 
  5        this  .subscription.unsubscribe();
   6        this .isWatched =  false ;  //   按钮的状态的变化 
  7        this .subscription =  null ;  //   将流的对象置空 
  8      }  else   {
   9         this .isWatched =  true ;  //   按钮的状态的变化 
 10         this .subscription =  this .wsService.createObservableSocket(\'ws://localhost:8090\',  this  .product.id)
  11         .subscribe(
  12           products =>  {
  13              products =  JSON.parse(products);
  14               console.log(products);
  15              let product = products.find(p => p.productId ==  this .product.id);  //  通过id筛选出当前的商品 
 16               this .currentBid = product.bid;  //   展示在页面上 
 17            }
  18         );
  19       }
  20    }

6. 重点是websocket的编程的流的创建和订阅,node服务器来模拟用户的访问和出价,对流的数据的处理。

对websocket的编程的流程有大概的了解。

 

查看更多关于angular5 websocket 商品价格 关注商品价格 在线商品竞拍的详细内容...

  阅读:35次