Node.js 将socket.io-client与Express和nodejs一起使用,将查询发送到java服务器
我有一个基于Express的web应用程序。nodejs后端使用java服务器执行一些繁重的操作。Express和java服务器之间的对话是使用socketio完成的。nodejs服务器是客户端,它使用socket.io-client向java服务器发送查询。javaserver基于netty socketio 以下是我在nodejs应用程序中的操作:Node.js 将socket.io-client与Express和nodejs一起使用,将查询发送到java服务器,node.js,express,socket.io,Node.js,Express,Socket.io,我有一个基于Express的web应用程序。nodejs后端使用java服务器执行一些繁重的操作。Express和java服务器之间的对话是使用socketio完成的。nodejs服务器是客户端,它使用socket.io-client向java服务器发送查询。javaserver基于netty socketio 以下是我在nodejs应用程序中的操作: var io = require('socket.io-client') var socket = io.connect('ht
var io = require('socket.io-client')
var socket = io.connect('http://localhost:8080');
socket.on('connect', function () {
console.log('0 Connected!');
socket.emit('myEvent', ['0' ,'here is the query'], function (data) {
console.log('\tSending query ... waiting for ACK0');
console.log(data);
});
socket.on('serverResponse', function (data) {
console.log('\tserverResponse event triggered, data:');
console.log(data);
});
});
在我的web应用程序外调用此脚本时,一切都很正常,但当我从express调用此代码时,我的客户端无法连接(我没有到达“0 Connected!”行)。没有错误消息
奇怪的是,如果我首先运行我的web应用程序,抛出一个查询,然后启动java服务器,客户端连接到java服务器,一切都正常工作(仅针对该查询)。关于如何解决这个问题有什么线索吗
编辑1
以下是我试图实现的目标的模式:
client javascript backend java server
via browser <---> node/Express/socketio-client <---> netty-socketio
@client's machine | @my server | @my server (the same)
| |
myDNS:80 localhost:8080
当我在java服务器关闭的情况下运行客户机时,我会收到一个“connect\u error”事件。当java服务器打开时,我根本没有收到任何消息。似乎连接既没有失败也没有成功,什么都没有发生。。。你知道如何更好地调试它吗
编辑3
下面是我用来处理浏览器请求的代码:
- index.js:
var express = require('express'); var router = express.Router(); var controller = require('../controllers/myController.js'); /* GET home page. */ router.get('/', function(req, res, next) { res.render('index', { title: 'Express' }); }); module.exports = router; router.post('/api/getProcessedData', function(req, res, next){ var text = req.body.text; controller.get_processed_data(text, res); });
- myController.js:
var socket = require('socket.io-client')('http://localhost:8080'); module.exports.get_processed_data = function(text, res) { var timestamp = new Date().getTime(); console.log('starting client'); socket.on('connect', function () { console.log("client connected."); socket.emit('myEvent', [timestamp ,text], function (data) { console.log('\tSending query ... waiting for ACK'); console.log(data); }); socket.on('serverResponse', function (data) { console.log('\tserverResponse' event trigged, data:'); res.send(data); }); }); socket.on('connect_error', function(err){ console.log(err); }); socket.on('connect_timeout', function(){ console.log("connect_timeout"); }); socket.on('reconnect_attempt', function(){ console.log("reconnect_attempt"); }); socket.on('reconnecting', function(){ console.log("reconnecting"); }); }
- 加载模块时,您连接到Java服务器,但在到达路由之前,您不会分配
事件处理程序。这意味着您通常会错过连接事件,除非服务器尚未运行。所以,这完全解释了你所观察到的。如果启动Express server时java服务器已经启动,则会错过connect事件,因此您永远不会执行connect
函数中的任何逻辑get\u processed\u data()
- 每次点击路由时,您都会安装一个新的连接处理程序,这意味着您将分配多个事件处理程序,尽管由于第一个问题,它们中没有一个可能会被点击 如果希望socket.io连接持续连接,这将是重写控制器的一种方法:
- 控制器的结构有点混乱。以下是一些错误的地方:
var socket = require('socket.io-client')('http://localhost:8080');
socket.on('connect', function () {
console.log("client connected.");
});
socket.on('connect_error', function(err){
console.log(err);
});
socket.on('connect_timeout', function(){
console.log("connect_timeout");
});
socket.on('reconnect_attempt', function(){
console.log("reconnect_attempt");
});
socket.on('reconnecting', function(){
console.log("reconnecting");
});
var transactionCntr = 0;
module.exports.get_processed_data = function(text, res) {
var timestamp = new Date().getTime();
var transactionId = transactionCntr++;
console.log('sending data to client');
function onResponse(data) {
// for concurrency reasons, make sure this is the right
// response. The server must return the same
// transactionId that it was sent
if (data.transactionId === transactionId) {
console.log('\tserverResponse' event trigged, data:');
res.send(data);
socket.off('serverResponse', onResponse);
}
}
socket.on('serverResponse', onResponse);
// send data and transactionId
socket.emit('myEvent', [timestamp ,text, transactionId], function (data) {
console.log('\tSending query ... waiting for ACK');
console.log(data);
});
}
您当前的结构存在一个问题,因为它似乎没有办法确定哪个响应与哪个请求相匹配,并且可能存在并发性问题。每次只使用一个单独的http请求会更简单,因为这样响应将与相应的请求唯一配对
通过socket.io连接,您可以在请求/响应中使用某种ID,这样您就可以知道哪个响应属于哪个请求。我已经展示了在express服务器中如何工作。在Java服务器上,您必须将transactionId回显到Express服务器的响应中,以便它能够跟踪哪个响应与哪个请求一起进行
正如您的代码一样,如果对'/api/getProcessedData'
路由的多个请求同时进行,那么来自不同请求的响应很容易混淆。这是你做事方式的架构问题
我不是Java专家,但在我看来是这样的:
Thread.sleep(60000*3);
将使线程休眠180000毫秒(3分钟),然后代码立即调用server.stop()
。因此,Java服务器会在3分钟后自动关闭
因此,您只能在启动Java服务器后的前3分钟内连接到它
这里的逻辑问题是,为什么要停止服务器?您的web应用程序运行在哪个端口上?Java服务器在哪个端口监听socket.io连接?我在最初的帖子中添加了一些信息,希望能有所帮助。如果您需要更多详细信息,请不要犹豫。这只是为了测试服务器,在最终版本中,它将是Thread.sleep(Integer.MAX_VALUE);。我只是懒惰,这样我就不必在eclipse中点击终止进程按钮。有趣的是,如果我首先运行我的节点服务器
npm start
,然后从web界面抛出一个post请求,该请求将调用我的socket.io-client脚本。如果没有java服务器正在侦听localhost:8080
。然后,当我启动java服务器时,就会创建连接并正确处理查询。当发出查询且没有服务器在侦听时,会发生绕过问题的情况。是否可以为发出的每个查询模拟此行为?@user3091275-是否有其他端口与8080竞争?@user3091275-能否在使用socket.io连接的Express中显示处理post操作的代码?这似乎就是问题所在。@user3091275-我添加了一个可能的编码解决方案。
var socket = require('socket.io-client')('http://localhost:8080');
socket.on('connect', function () {
console.log("client connected.");
});
socket.on('connect_error', function(err){
console.log(err);
});
socket.on('connect_timeout', function(){
console.log("connect_timeout");
});
socket.on('reconnect_attempt', function(){
console.log("reconnect_attempt");
});
socket.on('reconnecting', function(){
console.log("reconnecting");
});
var transactionCntr = 0;
module.exports.get_processed_data = function(text, res) {
var timestamp = new Date().getTime();
var transactionId = transactionCntr++;
console.log('sending data to client');
function onResponse(data) {
// for concurrency reasons, make sure this is the right
// response. The server must return the same
// transactionId that it was sent
if (data.transactionId === transactionId) {
console.log('\tserverResponse' event trigged, data:');
res.send(data);
socket.off('serverResponse', onResponse);
}
}
socket.on('serverResponse', onResponse);
// send data and transactionId
socket.emit('myEvent', [timestamp ,text, transactionId], function (data) {
console.log('\tSending query ... waiting for ACK');
console.log(data);
});
}
Thread.sleep(60000*3);