我正在寻找关于使用RxJS 5设置WebSocket连接的正确方法的一些指导。我正在连接到使用JSON-RPC 2.0的WebSocket。我希望能够执行一个向WS发送请求的函数,并从服务器返回相关响应的Observable。
我设置了我的初始WebSocketSubject,如下所示:
const ws = Rx.Observable.webSocket("<URL>")
从这个观察中,我已经能够使用ws.next(myRequest)
发送请求,并且我已经能够看到通过ws`观察到的响应。
我一直在努力创建能够过滤ws对正确响应的响应然后完成的函数。这些似乎完成了源主题,停止了所有未来的ws请求。
我的预期输出类似于:
function makeRequest(msg) {
// 1. send the message
// 2. return an Observable of the response from the message, and complete
}
我尝试了以下内容:
function makeRequest(msg) {
const id = msg.id;
ws.next(msg);
return ws
.filter(f => f.id === id)
.take(1);
}
但是,当我这样做时,只有第一个请求才有效。后续请求无法正常工作,我相信因为我正在完成take(1)
?
对这种情况的适当架构有何想法?
答案 0 :(得分:1)
如果没有其他订阅者,似乎有错误或故意设计决定关闭取消订阅WebSocket
。如果您对此感兴趣,请查看相关的source。
基本上,您需要保证始终有订阅者,否则WebSocket
将被关闭。你可以用两种方式做到这一点。
路线A是更具语义性的方式,基本上您创建了Observable
Subject
部分的已发布版本,您可以对其进行更精细的控制。
const ws = Rx.Observable.webSocket("<URL>");
const ws$ = ws.publish();
//When ready to start receiving messages
const totem = ws$.connect();
function makeRequest(msg) {
const { id } = msg;
ws.next(msg);
return ws$.first(f => f.id === id)
}
//When finished
totem.unsubscribe();
路由B是创建一个只保存套接字的令牌订阅,但是根据应用程序的实际生命周期,您可以很好地附加到某种关闭事件,以确保它始终关闭。即。
const ws = Rx.Observable.webSocket("<URL>");
const totem = ws.subscribe();
//Later when closing:
totem.unsubscribe();
正如您所看到的,两种方法都非常相似,因为它们都创建了订阅。 B的主要缺点是你创建了一个空的订阅,它将被抽取所有的事件只是为了扔掉它们。他们只有B的优势在于您可以使用相同的变量引用Subject
进行排放和订阅,而您必须注意使用ws$
进行订阅。
如果您真的如此倾向,可以使用Subject
创建功能来优化路线A:
const safeWS = Rx.Subject.create(ws, ws$);
以上内容允许您使用相同的变量,但是当您完成后,您仍然有责任关闭ws$
并传递WebSocket
。