我想在调用函数时从我的服务器向我的客户端发送消息。使用this answer消息中的代码可以每秒从服务器成功发送到客户端。
我正在构建一个在后台运行节点的应用程序,理想情况下我希望能够单击一个按钮,该按钮将调用节点server.js文件中的一个函数,该文件接受一个参数并将该消息发送给客户端。有问题的功能看起来像这样
function sendToClient(message) {
clients[0].emit('foo', msg);
}
这会将传入的消息发送给第一个客户端。我怎么能这样做呢?
在终端中,运行node server.js
之后有一种方法可以使用终端从服务器文件调用函数,如果是这样,这可能是一种可能的解决方案。
答案 0 :(得分:4)
现在将消息从服务器发送到客户端的最佳方法是使用webSockets。基本概念是:
支持webSocket支持非常简单的流行node.js库是socket.io
。它具有客户端和服务器支持,因此您可以为连接的两端使用相同的库。 socket.io库支持您在问题中提到的.emit()
方法,用于通过活动的webSocket连接发送消息。
您不直接从客户端到服务器调用函数。相反,您发送的消息会触发服务器运行某些特定代码,反之亦然。这是合作编程,其中必须对远程端进行编码以支持您要求它执行的操作,因此您可以向其发送消息和一些可选数据以与消息一起使用,然后它可以接收该消息和数据并执行一些代码。
因此,假设您希望服务器在温度发生变化时随时告诉客户端,以便客户端可以在其网页中显示更新的温度(我实际上有一个Raspberry Pi node.js服务器就是这样做的)。在这种情况下,客户端网页在页面加载时建立与服务器的webSocket连接。同时,服务器有自己的过程来监控温度变化。当它发现温度已经改变了一些有意义的量时,它会使用新的温度数据向每个连接的客户端发送温度变化消息。客户端接收该消息和数据,然后使用它来更新它的UI以显示新的温度值。
交易也可能反过来。客户端可能有一个信息矩阵,它希望服务器执行一些复杂的计算。它将使用消息类型中指示的计算类型向服务器发送消息,然后将矩阵作为消息的数据发送。服务器将接收该消息,看到这是对某些数据执行特定类型计算的请求,然后它将调用适当的服务器端函数并将其传递给客户端数据。当结果在服务器上完成时,它会将结果发送回客户端。客户端将收到该结果,然后根据计算结果执行所需操作。
注意,如果事务只是从客户端到服务器,并且响应然后从服务器返回,则该类型的事务不需要webSocket。这可以通过Ajax调用来完成。客户端对服务器进行ajax调用,服务器制定响应并返回响应。 webSockets最有用的地方是,如果要从服务器启动通信,并在服务器决定的时间将未经请求的数据发送到客户端。为此,您需要在客户端和服务器之间建立连续的连接,这就是webSocket的设计目标。
看来您可能还有更多关于如何从C#服务器与node.js服务器进行通信的问题,以便它可以通知客户端。如果是这种情况,那么由于node.js服务器已经是一个Web服务器,我只需要添加一个到node.js服务器的路由,这样你就可以简单地从C#服务器向node.js服务器发出一个http请求。将一些数据传递给node.js服务器,然后它可以用来通过上述webSocket连接通知相应的客户端。根据您的安全需求,您可能希望实现某种级别的安全性,以便http请求只能从您的C#服务器本地发送,而不是从外部世界发送到您的node.js服务器。
答案 1 :(得分:2)
为了通过控制台向客户端发送命令,有两个选项,单进程或多进程:
socket.io
服务器开始侦听端口。这样做的原因是socket.io
个客户端总是试图连接到服务器。只要浏览器打开,他们就会尝试连接。因此,即使服务器仅启动几秒钟,它也应该连接并接收消息。如果客户端未运行,则只需创建一个超时,该超时将停止控制台应用程序并通知用户它无法广播该命令。
虽然这种方法非常简单,但它并不健全且效率不高。对于小型项目,这可行,但您可以在下一个方法中获得更好的运气:
当您谈论架构时,这种方法更可靠,可扩展,更好看。这是基本摘要:
node
应用,它会向服务器发送消息以转发给客户。这种技术只是进程间通信。幸运的是,您已经在主服务器上安装了Socket.IO,因此您的控制台应用程序只需要是另一个socket.io
客户端。 Check out this answer on how to implement that.
这样做的缺点是你必须保护套接字通信。也许您可以强制它只允许localhost
个连接,这样您就需要访问服务器才能发送run command
消息(您绝对不希望Web客户端在其他网站上执行代码网络客户)。
总的来说,它归结为您项目的需求。如果您想尝试这是一个快速的小实验,那么只需单个过程即可。但是,如果要托管一个快速服务器(其他网络服务器可用)并且无论如何都需要运行,那么多进程是可行的方法!
我仅使用Socket.io创建了simple example of this进程。运行它的说明都在自述文件中。
为了拥有C#(app
) - > Node.js(server
) - >浏览器(client
)通信然后我将执行以下操作之一:
app
将项目添加到队列中,使用server
消费,将命令发送到client
)。app
向server
发送消息(消息由server
处理,就像其他任何socket.io
一样客户端 - 服务器模型)。System.Diagnostics.Process
启动多进程部分中说明的控制台工具。这将简单地使用任意参数运行该过程。不是很强大但值得考虑,简单意味着更难破解(然后,消息由server
处理,就像任何其他socket.io
客户端 - 服务器模型一样。)答案 2 :(得分:0)
我会创建一条路由来发送消息并从post参数发送消息。从CLI您可以使用curl或从任何地方:
app.get('/create', function(req, res) {
if( data.type && data.content && data.listeners){
notify( data );
}
});
var notify = function( notification ){
ns_mynamespace.in(notification.listeners.users)
.emit("notification", {
id: notification.id,
title: 'hello', text: notification.content });
}
}