Ionic2长轮询:在更改页面时终止http.get请求

Ionic2长轮询:在更改页面时终止http.get请求,http,ionic2,Http,Ionic2,我的服务器是在Node.js上开发的。它是一种长轮询服务,例如聊天:它提供以下API: join() //listening for new events align(fromId) //retrieving events from an id send(data) //creating an event 长轮询是由连接实现的:它发送一个请求,服务器在出现新事件时进行应答 前端带有Ionic2 共有2页:第1页和第2页。其中Page2是my events的查看器,其中长轮询通信正在运行 所以我

我的服务器是在Node.js上开发的。它是一种长轮询服务,例如聊天:它提供以下API:

join() //listening for new events
align(fromId) //retrieving events from an id
send(data) //creating an event
长轮询是由连接实现的:它发送一个请求,服务器在出现新事件时进行应答

前端带有Ionic2

共有2页:第1页和第2页。其中Page2是my events的查看器,其中长轮询通信正在运行

所以我从第一页开始,然后推第二页第二页。直到现在一切都很好;但是如果我弹出Page2,然后再次按下Page2,那么我可以看到仍然在运行我的Page2的前一个实例的连接。这种行为会创建重复的连接:如果我多次推/弹出页面2,我将与服务器进行多次长轮询通信

因此,我试图找到一种方法,在离开页面时终止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);
    }
my 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() {
    }

}
回到我的问题上来:
如果不使用,我如何终止加入?终止我的Page2的HTTP.get请求实例,以防止重复加入?

我认为,如果您有一个提供程序全局添加到应用程序的“提供程序”部分,这意味着它可以作为一个应用程序,那么您可以使用以下选项:

每次第2页调用提供程序的join方法时,请检查提供程序中的hasAlreadyJoined布尔变量。 每次调用join方法时,此变量都设置为true。 如果尚未调用联接,则调用它并相应地更新变量。 因此,即使每次第2页调用MyProvider的join方法,只有当HasalReadyJoin为false时,该方法才会执行实际的http请求

为了确保每次启动MyProvider实例时其变量都是静态的,应该在应用程序模块文件的“全局提供程序”部分声明提供程序,而不是在页面的“提供程序”部分声明提供程序