сборщиков JavaScript и создает статистику.
Я использую Springboot для установки сервера и создал javascript-файл для управления полученными сообщениями и вызова скрапера в зависимости от полученного сообщения. (Я полностью осознаю, что могу просто использовать Java-процессы для вызова каждого бота индивидуально, когда мне нужно, и получать выходные данные из inputStream, но я хотел запачкать руки Springboot и узнать еще пару вещей)
Чтобы это работало, мне пришлось создать «сервер» со стороны js, чтобы Java могла отправлять сообщения, но это, очевидно, должен быть запущен первым (перед Java-сервером), и вместо того, чтобы самостоятельно запускать файл js (через вызов терминала), я хотел использовать ProcessBuilder в Java, чтобы он вызывал файл js для запуска, затем запускал сервер Springboot и отправлял сообщение .
Проблема в том, что я получаю сообщение об ошибке сразу после моего Threshold.sleep(5000);, в котором говорится, что адрес с сервера js уже используется, когда Springboot-сервер запускается. Я пробовал это, не запуская Springboot, и не получаю этого сообщения об ошибке.
Вот Java-метод, который объединяет все воедино:
Код: Выделить всё
public void run_scrapper(String spec) throws IOException, InterruptedException, SQLException
{
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command("node", "./lib/webs/BotController.js");
processBuilder.inheritIO();
Process p = processBuilder.start();
long pid=p.pid();
System.out.println(pid);
Thread.sleep(5000);
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class);
BotController botController = context.getBean(BotController.class);
if(spec=="whatever")
{
String s=botController.executeBot("whatever");
RawFileLoader rf = new RawFileLoader();
send_toDb("toscan",rf.create_raw(s));
}
p.destroyForcibly();
SpringApplication.exit(context, () -> 0);
}
/>Хотя после запуска Java-сервера я получаю это сообщение об ошибке:
Код: Выделить всё
11956
BotController is listening on port 3000
20840
node:events:497
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE: address already in use :::3000
at Server.setupListenHandle [as _listen2] (node:net:1898:16)
at listenInCluster (node:net:1946:12)
at Server.listen (node:net:2044:7)
at Module._compile (node:internal/modules/cjs/loader:1358:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1416:10)
at Module.load (node:internal/modules/cjs/loader:1208:32)
at Module._load (node:internal/modules/cjs/loader:1024:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:174:12)
Emitted 'error' event on Server instance at:
at emitErrorNT (node:net:1925:8)
at process.processTicksAndRejections (node:internal/process/task_queues:82:21) {
code: 'EADDRINUSE',
errno: -4091,
syscall: 'listen',
address: '::',
port: 3000
}
Node.js v20.14.0
Я также использовал netstat -nba |FINDSTR "LISTEN" |FINDSTR "3000" в Windows cmd, чтобы проверить, работает ли js-сервер, прежде чем запускать Java-проект, но все в порядке.
**Я также проверил tomcat, который работает на порту 8080
Я также столкнулся с тем фактом, что процесс js никогда не завершается в моем Java-коде, даже несмотря на то, что я использую p.destroyForcily(), ЕСЛИ я не делаю вызов server.close() в моем js-файле
(я снова вручную проверил через Windows cmd, выполнив файл js --> проверка сеанса localhost на этом порту ----> прекращение выполнения js ----> повторная проверка сеанса locahost, и он завершается. Поэтому я предположил, что это также будет работать с использованием p.destroyForcily(); в Java):
Код: Выделить всё
const fetch = require('node-fetch');
const index= require('./index.js');
const scanner=require('./app.js');
const express = require('express');
const app = express();
const port = 3000;
async function call_index()
{
let v;
v=await index.main();
while(v==undefined)
{
v=await index.main();
}
return v;
}
app.use(express.json());
app.post('/run-bot', async(req, res) => {
const task = req.body.task;
console.log('Received task:', task);
let result;
if (task === 'whatever') {
result= await call_index();
} else {
const array=task.split('\n');
console.log(array);
//result=await scanner.main(array);
console.log(task);
}
res.send(result);
server.close();
});
var server=app.listen(port, () => {
console.log(`BotController is listening on port ${port}`);
});
а) я вижу, что терминал в Java никогда не завершает работу, и
b)я также использую список задач /fi "pid eq current_pid" в cmd после завершения очистки и получаю работающий сеанс
(я точно знаю, что мой скрапер готов, потому что я распечатываю выходные данные)
**PS. я используюprocessBuilder.inheritIO(); из-за того, что мой бот был прерван при выполнении задач, которые я хотел.
если я закомментирую это, оно «складывается» после вызова console.log(), и это кажется, никогда не будет продолжаться.
Я также использовал эту функцию в своем индексном js-файле, чтобы отправлять сообщения в Java, например, распечатывать текущий статус бота:
Код: Выделить всё
async function sendLogToJava(logMessage) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 seconds timeout
try {
const response= await fetch('http://localhost:8080/receiveBotLog', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ log: logMessage }),
signal: controller.signal
});
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error('Network response was not ok');
}
} catch (error) {
console.error('Error sending log to Java:', error);
}
}
Подробнее здесь: https://stackoverflow.com/questions/789 ... r-when-sta