一个 HTTP 实例如何知道要调用 WebSocket 实例?
How an HTTP Instance knows with WebSocket Instance to call?
在这种情况下,我在 Cloud Foundry 中遇到了一个问题:
- 设备连接到 Cloud foundry 中的 WebSocket 实例
- 那么,CF中只有一个实例持有socket连接
- AngularUI向REST实例发送请求
- REST 实例必须在设备上执行操作
问题:
如何调用正确的 WebSocket 实例来访问设备?
谢谢!
塞尔。
这有点复杂,但这是可能的。先来看看get stats for a process。您可以将其与 X-CF-APP-INSTANCE
header 一起使用,以访问每个实例并查看哪个具有您正在寻找的 websocket 连接。
How an HTTP Instance knows with WebSocket Instance to call?
我的回答是:他们不应该。
管理实例信息和用户连接数据的内部池会增加复杂性并成为可扩展性(和可维护性)的障碍。
How do I call the right WebSocket instance to get to the device?
恕我直言,最好的方法是使用 pub/sub 数据库,例如 Redis(或 pub/sub 服务,这是更昂贵的解决方案)。
WebSocket 连接实例 "subscribes"(侦听)唯一私有 "channel"(pub/sub 消息流)。
REST 连接 "publishes"(发送数据)到通道。
如果用户在线,他们将收听(订阅)并且他们将使用 "push" 方法接收数据(不需要轮询)。如果没有人在听,消息就会消失在虚无中。
WebSocket 连接还可以订阅一个 public / 全局通道以获取全局通知。
这种方法在发送者/发布者(REST 调用)和接收者(订阅的 WebSocket)之间创建了一个分离。
这使得扩展变得非常容易,因为 pub/sub 数据库(在本例中为 Redis)将处理所需的任何消息转发。
这也将允许单个用户从不同的机器(即笔记本电脑和 phone)连接并在两台机器上接收通知,而无需处理 IP 地址,也无需将用户路由到一台特定的服务器机器。
如我所写,我不想设置像 RabbitMQ 这样的消息系统,只是为了通过 Web 套接字向设备发送简单的命令。太过分了!
经过搜索,我终于找到了针对正确实例的解决方案。
1\当设备向WebSocket服务器打开web socket时,我将CF App ID + CF Instance Index以"APP_ID:INSTANCE_INDEX".
的形式保存在数据库中
您可以在 CF 环境中的 nodejs 下通过此代码检索此信息。变量:
const cfenv = require('cfenv');
let appID = cfenv.getAppEnv().app.application_id;
let instanceIndex = cfenv.getAppEnv().app.instance_index;
2\ 当用户在 Angular UI 中触发将调用 REST 服务器的操作时,此服务器接收命令并从数据库中检索 "APP_ID:INSTANCE_INDEX"给定设备。
3\ 接下来,我从 REST 服务器向 WebSocket 服务器打开一个 WebSocket,该 WebSocket 服务器准确地定位了包含目标设备所连接的套接字的实例,方法是添加此 HTTP header:"X-CF-APP-INSTANCE":"APP_ID:INSTANCE_INDEX".
// Create WS
this._wsConnection = new WebSocket(this._serverURL, {
protocol: 'rest',
headers: { 'X-CF-APP-INSTANCE': 'APP_ID:INSTANCE_INDEX' }
});
4\ WebSocket 服务器从 REST 服务器接收请求并使用正确的设备处理它,然后 return 将结果发送到 REST 服务器,该服务器将 return 它到 Angular UI.
瞧瞧!
解决问题 !
在这种情况下,我在 Cloud Foundry 中遇到了一个问题:
- 设备连接到 Cloud foundry 中的 WebSocket 实例
- 那么,CF中只有一个实例持有socket连接
- AngularUI向REST实例发送请求
- REST 实例必须在设备上执行操作
问题:
如何调用正确的 WebSocket 实例来访问设备?
谢谢!
塞尔。
这有点复杂,但这是可能的。先来看看get stats for a process。您可以将其与 X-CF-APP-INSTANCE
header 一起使用,以访问每个实例并查看哪个具有您正在寻找的 websocket 连接。
How an HTTP Instance knows with WebSocket Instance to call?
我的回答是:他们不应该。
管理实例信息和用户连接数据的内部池会增加复杂性并成为可扩展性(和可维护性)的障碍。
How do I call the right WebSocket instance to get to the device?
恕我直言,最好的方法是使用 pub/sub 数据库,例如 Redis(或 pub/sub 服务,这是更昂贵的解决方案)。
WebSocket 连接实例 "subscribes"(侦听)唯一私有 "channel"(pub/sub 消息流)。
REST 连接 "publishes"(发送数据)到通道。
如果用户在线,他们将收听(订阅)并且他们将使用 "push" 方法接收数据(不需要轮询)。如果没有人在听,消息就会消失在虚无中。
WebSocket 连接还可以订阅一个 public / 全局通道以获取全局通知。
这种方法在发送者/发布者(REST 调用)和接收者(订阅的 WebSocket)之间创建了一个分离。
这使得扩展变得非常容易,因为 pub/sub 数据库(在本例中为 Redis)将处理所需的任何消息转发。
这也将允许单个用户从不同的机器(即笔记本电脑和 phone)连接并在两台机器上接收通知,而无需处理 IP 地址,也无需将用户路由到一台特定的服务器机器。
如我所写,我不想设置像 RabbitMQ 这样的消息系统,只是为了通过 Web 套接字向设备发送简单的命令。太过分了!
经过搜索,我终于找到了针对正确实例的解决方案。
1\当设备向WebSocket服务器打开web socket时,我将CF App ID + CF Instance Index以"APP_ID:INSTANCE_INDEX".
的形式保存在数据库中您可以在 CF 环境中的 nodejs 下通过此代码检索此信息。变量:
const cfenv = require('cfenv');
let appID = cfenv.getAppEnv().app.application_id;
let instanceIndex = cfenv.getAppEnv().app.instance_index;
2\ 当用户在 Angular UI 中触发将调用 REST 服务器的操作时,此服务器接收命令并从数据库中检索 "APP_ID:INSTANCE_INDEX"给定设备。
3\ 接下来,我从 REST 服务器向 WebSocket 服务器打开一个 WebSocket,该 WebSocket 服务器准确地定位了包含目标设备所连接的套接字的实例,方法是添加此 HTTP header:"X-CF-APP-INSTANCE":"APP_ID:INSTANCE_INDEX".
// Create WS
this._wsConnection = new WebSocket(this._serverURL, {
protocol: 'rest',
headers: { 'X-CF-APP-INSTANCE': 'APP_ID:INSTANCE_INDEX' }
});
4\ WebSocket 服务器从 REST 服务器接收请求并使用正确的设备处理它,然后 return 将结果发送到 REST 服务器,该服务器将 return 它到 Angular UI.
瞧瞧! 解决问题 !