我不确定,如果我使用的是错误的方法,或者我的编码很糟糕,而是解释我的问题。
我有一个后端组件,我在其中管理websockets数组(因为每个websocket都可以有不同的WS url,或者它们需要单独关闭/打开),对于每个websocket,我想知道它的状态和通过Rx.Subject将其发送到视图(如果它已打开,关闭或者它没有连接所需的数据)
看起来
public class MyTest {
private static double START = 0;
private static double END = 100;
private static double INCREMENT = 0.0001;
@Test
public void testFirst() throws Exception {
long time = System.nanoTime();
for (double bMI = START; bMI < END; bMI += INCREMENT) {
first(bMI);
}
System.out.println("First " + (System.nanoTime() - time));
}
@Test
public void testSecond() throws Exception {
long time = System.nanoTime();
for (double bMI = START; bMI < END; bMI += INCREMENT) {
second(bMI);
}
System.out.println("Second " + (System.nanoTime() - time));
}
private String first(double bMI) {
String weightStatus = "Underweight";
if (bMI > 29.9) {
weightStatus = "Obese";
} else if (bMI >= 25.0) {
weightStatus = "Overweight";
} else if (bMI >= 18.5) {
weightStatus = "Healthy Weight";
}
return weightStatus;
}
private String second(double bMI) {
String weightStatus;
if (bMI > 29.9) {
weightStatus = "Obese";
} else if (bMI >= 25.0) {
weightStatus = "Overweight";
} else if (bMI >= 18.5) {
weightStatus = "Healthy Weight";
} else {
weightStatus = "Underweight";
}
return weightStatus;
}
}
这可行。
在我看来,我已经定义了
public connectDeviceTerminalWebSocket(server: string, port: string): void {
if (!(server !== null) && !(port !== null)) {
let websocket: WebSocket = null;
let wsPosition: number = this.hardwareTerminalwebSockets.findIndex(ws => {
if (ws.url.includes(server + ':' + port)) {
websocket = ws;
return true;
}
});
if (websocket) {
this.closeHardwareTerminalWebsocket(websocket.url);
}
websocket = new WebSocket(`${this.wsProtocol}://${server}:${port}/${this.getToken()}`);
websocket.addEventListener('close', ws => {
this.reconnectTerminalWebSocketAfterTimeout();
this.hardwareTerminalState.next({ 'websocketUrl': websocket.url, 'isConnected': false, 'reason': 'conectionFailed' });
});
websocket.addEventListener('open', ws => {
this.reconnectTerminalWebSocketAfterTimeout();
this.hardwareTerminalState.next({ 'websocketUrl': websocket.url, 'isConnected': true, 'reason': 'connected' });
});
let opened = Rx.Observable
.fromEvent<void>(websocket, 'open');
let channelReceived = Rx.Observable
.fromEvent<MessageEvent>(websocket, 'message')
.map(event => {
try {
return JSON.parse(event.data);
} catch (e) {
console.error('Parse error: ', e);
}
return null;
});
channelReceived
.filter(message => message.message_channel === 'hardware-logger')
.subscribe(this.hardwareTerminal);
opened.subscribe(open => this.sendWebSocketTerminalMessageQueue());
if (wsPosition > -1) {
this.hardwareTerminalwebSockets[wsPosition] = websocket;
} else {
this.hardwareTerminalwebSockets.push(websocket);
}
} else {
this.hardwareTerminalState.next({ websocketUrl: null, isConnected: null, 'reason': 'cantConnect' });
return;
}
}
我只用这种方式订阅
hardwareTerminalStateWS: Rx.Subject<ITerminalWebsocketMessage>;
和我视图中的ngOnDestroy
this.hardwareTerminalStateWS.subscribe(msg => this.onStateMessage(msg));
取消赞成。
现在主要问题如果我关闭/更改为其他视图,然后返回(例如重新打开并再次订阅)则会抛出错误
&#34; ./hwcomponent类中的错误hwComponent - 内联模板:47:28导致:object unsubscribed&#34;
我应该将Rx.Subject更改为其他类(Observer?)?或者使用不同的方法关闭hardwareTerminalStateWS? 因为如果我不关闭它,下次我再次打开视图时,它会打开第二个hardwareTerminalStateWS并读取每个messeage两次。
答案 0 :(得分:2)
如果您使用unsubscribe
而不是Subject
致电Subscription
,则无法再使用Subject
。
有关详细信息,请参阅this answer和Ben Lesh的中篇文章On The Subject Of Subjects:
如果您希望主题在
next
完成后对其进行大声和愤怒的错误,您可以直接在主题实例上调用unsubscribe
。
如果您打算重复某个主题,请拨打unsubscribe
上的Subscription
(通过调用subscribe
返回)。
此外,应该注意的是,在unsubscribe
上调用Subject
与在unsubscribe
上调用Subscription
的效果不同。通常,您可以在unsubscribe
上致电Subscription
,如果您想确保无法重复使用unsubscribe
,也可以致电Subject
。