【问题标题】:communication between node.js and java server on localhostnode.js 和本地主机上的 java 服务器之间的通信
【发布时间】:2015-06-07 07:39:04
【问题描述】:

我有一个使用 nodejs 构建的 Web 应用程序。后端正在调用几个 java 命令行来回答查询。这些 java 程序依赖于非常大的模型(大约 50Mo),并且对于每个执行的 java 命令行,都需要重新加载模型。最后,大部分回答时间都花在了将这些模型加载到 RAM 中。

我想做的是与nodejs一起设置一个java服务器,并使这两个服务器通信。 java 服务器会将模型保存在 RAM 中并处理所有 java 处理。问题是节点是异步的,我想在我的 java 服务器结束处理数据时触发回调。你知道有什么好方法吗?是否可以从节点向本地主机上的 java 发送某种 POST 请求?

编辑:

好的,因为 jfriend00Pelit Mamani 回答了我,我已经取得了一些进展。我决定使用jfriend00 的解决方案来使用socket.io。这正是我想做的事情(在 javascript 中):

  • 我有一台服务器(我想在 Java 中使用,这里是 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);
    
  • 我有一个客户端(在我的情况下,它将是我的 nodejs 服务器):

    // 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 客户端运行此服务器时,一切正常:

  • 在客户端:

    Connected!
        Sending query ...
    I am the answer from the Server!
    
  • 在服务器端:

    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 来发送这样的数据。我可能会改变另一个实现。待续……

【问题讨论】:

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

标签: java node.js socket.io netty


【解决方案1】:
  1. 如果您使用 http 或 tcp,node.js 是异步的这一事实并不能阻止 java 端“同步”工作......例如如果您有一个标准 Servlet 读取请求并写入回复(在同一线程上),它仍将转换为 node.js 端的标准异步代码。它会发送请求,然后在 java 应答时获得回调......

  2. 作为旁注,您可能还想了解异步队列协议,例如 Rabbit MQ,但这超出了您描述的基本要求。例如。这取决于您需要的通信有多可靠,如果 java 服务器崩溃会发生什么,等等。

【讨论】:

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