2017-02-22 19 views
0

Мой сервер разработан на Node.js. Это услуга давно опроса (например, чат): он дает следующий API:Ionic2-Long Опрос: убийство запроса http.get при смене страниц

join() //listening for new events 
align(fromId) //retrieving events from an id 
send(data) //creating an event 

пролонгированный опрос реализуемое объединение(): он посылает запрос и ответы сервера, когда есть новый мероприятие.

Передняя часть с Ionic2

Есть 2 страницы: Page 1 и Page2. Где Page2 - это просмотр моих событий, в которых работает связь с длинным опросом.

Итак, я начинаю с Page1, а затем нажимаю() вторую страницу Page2. До сих пор все работает нормально; но если я pop() Page2, а затем нажмите() снова Page2, то я вижу, что все еще работает join() предыдущего экземпляра моего Page2. Такое поведение создает дублируемое join(): если я нажимаю/pop Page2 много раз, у меня будет много длинного опроса связи с сервером.

Итак, я пытаюсь найти способ убить экземпляр join(), который является запросом HTTP.get, при выходе из страницы.

Теперь посмотрим мой код. Это поставщик моего Ionic2, отвечающий за связь с сервером

import { Injectable } from '@angular/core'; 
import { Http, Headers } from '@angular/http'; 
import {Observable} from 'rxjs/Observable'; 
import 'rxjs/add/operator/map'; 


@Injectable() 
export class MyProvider { 
    ... 

    constructor(private http: Http) { 
     this.token_access = null; 
     this.token_room = null; 
    } 

    ... 

    join(){ 
     let headers = new Headers(); 
     headers.append('Content-Type', 'application/json'); 
     headers.append('x-access-token',this.getToken()); 
     return Observable.create(observer =>{ 
      this.http.get('/localhost/chat/'+this.room,{headers : headers}) 
        .map(res => res.json()) 
        .subscribe(
         data=>{       
          observer.next(data); 
         }, 
         (err) =>{ 
          observer.error(err); 
         } 
        ); 
     }) 
    } 

    send(message){ 
     let headers = new Headers(); 
     headers.append('Content-Type', 'application/json'); 
     headers.append('x-access-token',this.getToken()); 
     headers.append('x-chat-token',this.getRoomToken()); 
     return Observable.create(observer =>{ 
      this.http.post('/localhost/chat/'+this.room+'/send', JSON.stringify({ 
          event: message 
         }),{headers : headers}) 
        .map(res => res.json()) 
        .subscribe(
         data=>{ 
          observer.next(data); 
         }, 
         (err) =>{ 
          observer.error(err); 
         } 
        ); 
     }) 
    } 

    align(from){ 
     let headers = new Headers(); 
     headers.append('Content-Type', 'application/json'); 
     headers.append('x-access-token',this.getToken()); 
     headers.append('x-chat-token',this.getRoomToken()); 
     return Observable.create(observer =>{ 
      this.http.post('/localhost/chat/'+this.room+'/align', JSON.stringify({ 
          fromId: from 
         }),{headers : headers}) 
        .map(res => res.json()) 
        .subscribe(
         data=>{ 
          observer.next(data); 
         }, 
         (err) =>{ 
          observer.error(err); 
         } 
        ); 
     }) 
    } 
} 

Page1 просто нажмите Page2 с помощью кнопки, которая вызывает следующий код (page1.ts):

... 
export class Page1 { 
    ... 

    constructor(public navCtrl: NavController, public myProviderService: MyProvider) { 

    } 

..... 


toPage2(){ 
     this.navCtrl.push(Page2); 
    } 

И мой Page2 реализуется следующим кодом:

import { Component } from '@angular/core'; 
import { NavController } from 'ionic-angular'; 
import { MyProvider } from '../../providers/myprovider'; 
import { Event } from '../../components/event'; 

@Component({ 
    selector: 'page-chat', 
    templateUrl: 'chat.html' 
}) 
export class ChatPage { 
    eventsList: Array<Event>; 
    message: any; 
    last_event: any; 
    msg: any; 

    constructor(public navCtrl: NavController, public myProviderService: MyProvider) { 
     this.last_event = -1; 
     this.join(); 
     this.eventsList= new Array(); 
    } 

    join(){ 
    this.myProviderService.join().subscribe(
     (data)=>{ 
      if(data.success){ 
       this.last_event = this.last_event + 1; 
       if(this.last_event == data.event.id){ 
        //up to now all events are correctly received 
        this.eventsList.push(data.event); 
       }else{ 
        //some events are missing 
        this.last_event = this.last_event - 1; 
        this.align(); 
       } 
       this.join(); 
      }else{ 
       this.message=data.message; 
       //TBD sleep.... 
       //this.join(); 
      } 
     }, 
     (err) => { 
      this.message="Connectivity with server Lost..."; 
      //TBD sleep.... 
      //this.join(); 
     }); 
    } 

    align(){ 
    this.myProviderService.align(this.last_event + 1).subscribe((data)=>{ 
     if(data.success){ 
      for (var i=0;i<data.events.length;i++) { 
       this.eventsList.push(new Event(data.events[i].id,data.events[i].data,data.events[i].user)); 
       this.last_event = this.last_event + 1; 
      }; 
     }else{ 
      this.message=data.message; 
     } 
    }, 
    (err) => { 
     this.message="Failure receiving messages"; 
    }); 
    } 

    send(): void{ 
     this.myProviderService.send(this.msg).subscribe((data)=>{ 
      if(data.success){ 
       this.msg=''; 
      }else this.message=data.message; 
     }, 
     (err) => { 
      this.message="Error while authenticating"; 
     }) 
    } 

    ionViewDidLoad() { 
    } 

    ionViewDidEnter() { 
    } 

} 

Итак, вернувшись к моему вопросу: Как я могу убить экземпляр join() (убить HTTP.get) моего Page2, если он не используется, чтобы предотвратить дублирование join()?

ответ

1

Я думаю, что если у вас есть поставщик, который глобально добавлен в Провайдер раздел вашего приложения (это означает, что он может выступать в качестве Singleton service), то вы можете использовать следующий:

  1. Каждый раз, когда страница 2 вызывает метод join() вашего провайдера, проверяя логическую переменную hasAlreadyJoined в вашем провайдере.
  2. Эта переменная имеет значение true при каждом вызове метода join().
  3. Если соединение() не было вызвано, вызовите его и соответствующим образом обновите переменную.

Так как каждый раз, когда вы вызываете метод join() MyProvider, этот метод выполняет фактический HTTP-запрос, только если hasAlreadyJoined является ложным.

Для вас, чтобы быть уверенными, что каждый раз, когда MyProvider экземпляр инициирует это переменные «статические», поставщик должен быть объявлен на глобальном Провайдеров раздел вашего файла модуль приложения , а не на + странице провайдеров раздел ,

Смежные вопросы