我的服务器是在node.js上开发的。这是一项长期播放服务(例如聊天):它提供以下API:
join() //listening for new events
align(fromId) //retrieving events from an id
send(data) //creating an event
长以通过JOIN()实现了长纸:它会在有新事件时发送请求,服务器答案。
前端带有Ionic2
有2页:Page
1和Page2
。其中Page2
是我事件的查看者,在该事件中正在运行长时间的通信。
所以我从Page1
开始,然后推()第二页Page2
。到目前为止,一切都很好。但是,如果我在 Page2
pop()然后再次推动()Page2
,那么我可以看到我的Page2
上一个实例的join()
仍在运行。此行为会创建重复的JOIN():如果我多次推动/pop Page2
,我将与服务器进行许多长时间的通信。
所以我试图找到一种杀死join()
实例的方法,这是http.get请求,离开页面时。
现在看看我的代码。这是我的离子2的提供商,负责与服务器的通信
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
只需用一个调用以下代码(page1.ts)的按钮按Page2
:
...
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() {
}
}
所以回到我的问题:当不使用该页面时,我如何杀死我的第2页的 join()
(杀死http.get请求)实例,以防止重复的 join()
?
我认为,如果您有一个全球添加到应用程序的提供商部分的提供商(这意味着它可以用作Singleton服务),那么您可以使用以下内容:ol>
因此,即使每次第2页都调用MyProvider的Join()方法,此方法仅在hasalDreadyjoined为false时才执行实际HTTP请求。
供您确保每次启动myProvider实例时,变量是"静态的",应在应用程序模块文件的 global 提供商部分上声明提供商,而不是在<<页面提供者部分。