我正在使用RxJs来监听来自websocket的数据流。为了使用这个pubsub套接字,我需要首先在另一个socket上进行身份验证,该套接字将返回pubsub套接字url。
我现在只使用一个订阅者。我需要添加另一个,但我当前的方法存在问题,因为两个订阅者都将触发身份验证并创建第二个pubsub套接字。
要明确的是,整个应用程序应该只有一个身份验证套接字和一个pubsub套接字。但是我需要订阅者在尝试使用pubsub套接字之前“等待”进行身份验证。否则,pubsub套接字将是未定义的(因为我们只在运行时知道它的url。)
这是我目前的尝试:
Websocket.service.ts
private connect(): Observable<IConnectionInfo> {
if (!this.authObservable) {
var credentials = {
"username": "bob",
"password": "slob"
}
this.authObservable = Observable.create((observer) => {
const socket = new WebSocket(this.authurl);
socket.onopen = () => {
console.log("Auth socket opened");
socket.send(JSON.stringify(credentials));
}
socket.onmessage = (event) => {
var connection_info = <IConnectionInfo>JSON.parse(event.data);
observer.next(connection_info);
}
return () => {
socket.close(); //invoked on unsubscribe
console.log("Auth socket closed");
}
})
}
return this.authObservable;
}
public open_pubsub(events: string[]): Observable<IPubSubMessage> {
return this.connect()
.flatMap((connection_info: IConnectionInfo) => {
var url = "ws://" + this.hostName + ":" + connection_info.port + "/" + connection_info.ps;
var subscription = {
"subscribe": events
}
var authenticate_request = {
"authenticate": connection_info['token']
}
if (!this.psObservable) {
this.psObservable = Observable.create((observer) => {
const socket = new WebSocket(url);
socket.onopen = () => {
console.log("PS socket opened");
socket.send(JSON.stringify(authenticate_request));
socket.send(JSON.stringify(subscription));
}
socket.onmessage = (event) => {
var psmsg = <IPubSubMessage>JSON.parse(event.data);
observer.next(psmsg);
}
return () => {
socket.close(); //invoked on unsubscribe
console.log("PS socked closed");
}
})
}
return this.psObservable;
}
);
}
观察员:
getSystemState(): Observable<string> {
return this._wsService.open_pubsub([MSG_SYSTEM_STATE_CHANGED])
.map((response: IPubSubMessage): string => {
console.log(response.payload);
return "I wish this worked";
})
.catch(this.handleError);
}
任何帮助表示赞赏!
(编辑根据似乎已被删除的答案,但实际上非常有用,我修改了代码。这解决了问题的一部分,但仍导致多个套接字)
答案 0 :(得分:0)
找到我所缺少的东西 - share()运算符的神奇之处。
因此,对于两个Observable,我这样做:
this.authObservable = Observable.create((observer) => {
...(etc)...
}).share();
令人惊讶的是,每个套接字只创建了一个。