应用程序不断尝试重新启动邮件服务,如何只运行一次邮件服务?

问题描述 投票:1回答:1

我有一个应用程序,运行带有2个可运行的执行程序服务,启动进程以接收来自rfid阅读器的消息。该阅读器接收来自messagelistener的消息,该消息包含标签已经被阅读器消失后的标签信息。我收到标签信息,但我在运行bc时收到错误,它一直试图重新启动messagelistenerservice。试图只添加需要看到的代码。我如何只启动messagelistener服务一次,所以我没有得到这个错误。谢谢!

这是错误:

java.io.IOException: Could not listen on port 3500. Is that port in use?
at com.alien.enterpriseRFID.notify.MessageListenerService.startService(MessageListenerService.java:232)
at com.rfidreader.volvo.model.AlienReader.startMessageService(AlienReader.java:99)
at com.rfidreader.volvo.model.AlienReader.<init>(AlienReader.java:73)
at com.rfidreader.volvo.VolvoRfidReaderApplication.lambda$1(VolvoRfidReaderApplication.java:54)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

这是给读者的@Component:

@Component
@Scope("prototype")
public class AlienReader extends AlienClass1Reader implements 
TagTableListener, MessageListener{

 private String ipaddress;
 private int port;
 private String username;
 private String password;
 private TagTable tagTable = new TagTable();
 private MessageListenerService service;
 private TagTableListener tagTableListener;


 private static final Logger log =LogManager.getLogger(AlienReader.class);

public AlienReader(String ipaddress, int port, String username, String pwd) 
throws UnknownHostException, AlienReaderException, InterruptedException{
    super(ipaddress, port);
    this.ipaddress=ipaddress;
    this.port=port;
    this.username=username;
    this.password=pwd;
    startMessageService();


    }

public void startMessageService() throws UnknownHostException, 
 AlienReaderException, InterruptedException{


    if(ipaddress.equals("222.22.222.22")){
        service=new MessageListenerService(3400);
        service.setMessageListener(this);
    }else if (ipaddress.equals("333.33.333.33")){
        service=new MessageListenerService(3500);
        service.setMessageListener(this);
    }

    try{
        service.startService();
     }catch(IOException e){
         e.printStackTrace();
     }
    log.info("Service has started on : "+ipaddress);
    setReaderConfig();
}

public void setReaderConfig() throws UnknownHostException, AlienReaderException, InterruptedException{
    log.info("Setting up reader");
     this.setUsername(username);
    this.setPassword(password);
      String myIP=InetAddress.getLocalHost().getHostAddress();
    try{
        this.open();
        this.setNotifyAddress(myIP,service.getListenerPort());
        this.setNotifyFormat(AlienClass1Reader.TEXT_FORMAT);
        this.setNotifyTrigger("TrueFalse");
        this.setNotifyMode(AlienClass1Reader.ON);
        this.autoModeReset();
        this.setAutoMode(AlienClass1Reader.ON);
        tagTable.setPersistTime(2000);
        this.close();
        }catch(AlienReaderException e){
            log.error("Reader "+ this.getIPAddress()+" did not connect."+e.getMessage());

        }


}


@Override
public synchronized void messageReceived(Message msg) {
     if(msg instanceof ErrorMessage){
         log.error("Notify error from "+ msg.getReaderIPAddress());

     }else if (msg.getTagCount() == 0){

                log.info("No tags!");
     }else{
        log.info("Message received from: "+msg.getReaderIPAddress());
         String location = msg.getReaderIPAddress();
        Tag[] tagL=msg.getTagList();
        for (int i=0;i<msg.getTagCount(); i++){
            Tag tag = msg.getTag(i);
            this.tagTable.addTag(tag);

            log.info("Tag ID: "+tag.getTagID()+ " Last Seen: "+tag.getRenewTime()+ " Receive Antenna: "+tag.getReceiveAntenna()+ " ip: "+ location);

        }

      }
}

这是启动String启动应用程序时的主要方法:

public static void main(String[] args) throws UnknownHostException, AlienReaderException, InterruptedException {
    //SpringApplication.run(VolvoRfidReaderApplication.class, args);
    ConfigurableApplicationContext run = SpringApplication.run(VolvoRfidReaderApplication.class, args);
    VolvoRfidReaderApplication app = run.getBean(VolvoRfidReaderApplication.class);
    app.run();
}

private void run(){
    Runnable r1= () -> {
        for(int i=0;i<30;++i){
            //System.out.println("task 1");
            try {
                new AlienReader("222.22.222.22", 22, "username","password");
            } catch (UnknownHostException | AlienReaderException | InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try{
                Thread.sleep(1000);
            }catch(Exception ignored){
        }
    }
};

    Runnable r2= () -> {
        for(int i=0;i<30;++i){
            //System.out.println("task 2");
            try {
                new AlienReader("333.33.333.33", 22, "username","password");
            } catch (UnknownHostException | AlienReaderException | InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try{
                Thread.sleep(1000);
            }catch(Exception ignored){
        }
    }
    };

        ExecutorService service = Executors.newFixedThreadPool(2);
        service.submit(r1);
        service.submit(r2);


        service.shutdown();
}
spring-boot executorservice
1个回答
1
投票

这里的主要错误是:

Could not listen on port 3500. Is that port in use?

端口只能在计算机上一次使用。所以,如果我有一个spring-boot网络应用程序,例如,它在端口8080上运行,我不能一次运行它的两个副本而不告诉第二个使用不同的端口,如8081。

你有一些逻辑可以选择2个不同的端口:

if(ipaddress.equals("222.2223")){
    service=new MessageListenerService(3400);
    service.setMessageListener(this);
}else if (ipaddress.equals("222.2224")){
    service=new MessageListenerService(3500);
    service.setMessageListener(this);
}

不幸的是,在你的for循环中,看起来你启动了多个具有相同IP的读者(奇怪的是,在这种情况下似乎不匹配23或24个结尾的那些,但我可能只是遗漏了一些东西)。

for(int i=0;i<30;++i){
    //System.out.println("task 1");
    try {
        new AlienReader("222.222", 22, "username","password");
    } catch (UnknownHostException | AlienReaderException | InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try{
        Thread.sleep(1000);
    }catch(Exception ignored){
}

您需要确保每次启动服务时,它都有一个完全唯一的端口,计算机上没有任何其他东西使用,或者您将继续看到此错误。

我认为你应该简化这个问题。现在只需在每个可运行的程序中运行一个阅读器,确保它们有自己独特的端口(我建议您从头开始手动传递),并在可用时将其扩展到更多。

© www.soinside.com 2019 - 2024. All rights reserved.