本地节点.js和Java服务器之间的通信

3
我有一个使用nodejs构建的Web应用程序。后端正在调用多个Java命令行来回答查询。那些Java程序依赖于相当大的模型(约50Mo),并且对于执行的每个Java命令行,都需要重新加载模型。最终,大部分响应时间都花在了将这些模型加载到RAM上。
我想做的是在nodejs服务器旁边设置一个Java服务器,并使这两个服务器通信。Java服务器将保持RAM中的模型并处理所有Java处理过程。问题是nodejs是异步的,并且我想在Java服务器结束处理数据时触发回调。您知道有什么好方法可以做到这一点吗?是否可能从node向localhost发送某种POST请求?
编辑:
好的,自jfriend00Pelit Mamani回答了我的问题之后,我取得了一些进展。我决定使用jfriend00的解决方案使用socket.io。以下是我想要做的事情的确切代码(这里是JavaScript):
  • I have a server (the one that I would like to have in Java, here in javascript)

    var http = require('http');
    
    console.log('Creating HTTP server');
    
    var server = http.createServer(function(req, res){
    });
    
    var io = require('socket.io').listen(server);
    
    io.sockets.on('connection', function(socket) { 
    
        console.log('Client connected.');
    
        // Disconnect listener
        socket.on('disconnect', function() {
            console.log('Client disconnected.');
        });
    
        socket.on('myEvent', function (data, fn) {
            console.log(data);
            console.log('\tSending answer ...');
            fn('\tI am the answer');
        });
    });
    
    server.listen(8080);
    
  • And I have a client (in my case it will be my nodejs server):

    // Connect to server
    var io = require('socket.io-client')
    var socket = io.connect('http://localhost:8080');
    
    socket.on('connect', function () {
    
        console.log('Connected!\n\tSending query ...');
    
        socket.emit('myEvent', '\tI am the query', function (data) {
          console.log(data); 
        });
    
    });
    
客户端发送请求,服务器回答请求,很简单。我正在使用netty-socketio在Java中实现服务器部分。这是我目前拥有的内容:
import java.io.UnsupportedEncodingException;

import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.Transport;
import com.corundumstudio.socketio.listener.*;

public class App {

    public static void main(String[] args) throws InterruptedException, UnsupportedEncodingException {

        Configuration config = new Configuration();
        config.setHostname("localhost");
        config.setPort(8080);

        final SocketIOServer server = new SocketIOServer(config);

        server.addConnectListener(new ConnectListener() {
            @Override
            public void onConnect(SocketIOClient client) {
                System.out.println("client connected !: "+client.toString());
            }
        });

        server.addEventListener("myEvent", String.class, new DataListener<String>() {
            @Override
            public void onData(final SocketIOClient client, String data, final AckRequest ackRequest) {
                System.out.println("myEvent triggered");

                System.out.println("Here is the query from the client: \n"+data);

                ackRequest.sendAckData("I am the answer from the Server!");
            }
        });

        server.addDisconnectListener(new DisconnectListener() {
            @Override
            public void onDisconnect(SocketIOClient client) {
                System.out.println("client disconnected !: "+client.toString());
            }
        });

        server.start();
        System.out.println("server started");

        Thread.sleep(20000);//Integer.MAX_VALUE);

        server.stop();
        System.out.println("server stopped");
    }

}

当我用我的JavaScript客户端运行这个服务器时,一切正常:
  • On the client side:

    Connected!
        Sending query ...
    I am the answer from the Server!
    
  • On the server side:

    server started
    client connected !: com.corundumstudio.socketio.transport.NamespaceClient@ecac7898
    myEvent triggered
    Here is the query from the client: 
        I am the query
    client disconnected !: com.corundumstudio.socketio.transport.NamespaceClient@ecac7898
    

但我认为 AckRequest 不应该用于发送那样的数据。我可能会改用另一种实现方式。待续...


1
Node.js服务器和Java服务器可以使用任何常见的网络技术(如http请求、socket.io消息、自定义TCP协议等)异步通信。我不明白为什么您认为node.js的异步特性会对您造成问题,因为所有的网络通信都已经是异步的了。您只需要让Java服务器在处理完成后向node.js服务器发送一条消息,然后node.js服务器就可以调用之前注册的某个回调函数。 - jfriend00
我困惑的地方在于我的Java服务器如何向Node发送消息并触发一些回调。这是我的第一个Web应用程序,第一个Node.js服务器和第一个Java服务器,如果您能为我指出一些示例代码,我将不胜感激。 - user3091275
2
正如我所说,您可以使用各种通信机制。一个相对简单的基于消息的解决方案是两者之间的socket.io连接。然后,当您想要启动某些操作时,只需从nodejs服务器发送一条消息到Java进程,然后Java服务器在完成后发送一条消息回来。这里有多个Java的socket.io实现这里这里 - jfriend00
这是一个使用Node.js服务器作为Socket.io客户端连接到另一个Socket.io服务器的示例在这里 - jfriend00
1个回答

1
如果您使用http或tcp,node.js是异步的事实并不会阻止java端“同步”工作...例如,如果您有一个标准的Servlet读取请求并写入回复(在同一线程上),它仍将转换为node.js端的标准异步代码。它将发送请求,然后在java回答时获得回调...
另外,您可能还想查看异步排队协议(例如Rabbit MQ),但这超出了您描述的基本要求。例如,这取决于您需要通信的可靠性如何,如果java服务器崩溃会发生什么等。

谢谢你的回答。我对这一切都很陌生,我已经尝试使用TCP。使用TCP时,当我的Java服务器接收到数据时,它不知道是谁发送的,所有数据都呈现为一个大流,我可以有多个请求连接在一起。我需要在处理之前将我的数据拆分并排队进行同步处理。处理完成后,我想触发特定的回调,但由于节点的异步行为,我无法通过观察接收数据的顺序来识别进程。我不知道如何触发适当的回调函数。 - user3091275
没有确切的代码很难准确,但归结为两种选择:(1)如果您的Java工作同步,意味着请求连接(通过该连接客户端发送其请求)保持打开状态等待回复,则由您确保您的内部代码可以访问该连接的响应输出流。例如在您的内部方法中传播它。(2)如果您使用一些异步协议,例如Rabbit,意味着您的请求连接可能会丢失 - 那么您将别无选择,只能更改设计以便您知道请求的来源。 - Pelit Mamani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接