J'ai créé une application web avec spring-boot. Lorsque l'application web démarre il y a une lecture blocante sur le port série qui démare. J'utilise la librairie: https://github.com/RishiGupta12/SerialPundit

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
    @Component
    public class ScanApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {
        @Autowired
        public ScanRead scanRead;
 
        @Override
        public void onApplicationEvent(final ApplicationReadyEvent event) {
            scanRead.run();
        }
    }
My thread code

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
 
    @Component
    public class ScanRead implements Runnable {
 
        @Autowired
        private SerialComManager scm;
 
        private long handle;
        private long context;
 
        Thread thrd;
        boolean suspended;
        boolean stopped;
 
        String port = "/dev/ttyUSB0";
 
        final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
 
        public String bytesToHex(byte[] bytes) {
            char[] hexChars = new char[bytes.length * 2];
            for (int j = 0; j < bytes.length; j++) {
                int v = bytes[j] & 0xFF;
                hexChars[j * 2] = hexArray[v >>> 4];
                hexChars[j * 2 + 1] = hexArray[v & 0x0F];
            }
            return new String(hexChars);
        }
 
        @Override
        public void run() {
            System.out.println("run");
            try {
 
                handle = scm.openComPort(port, true, false, true);
                scm.configureComPortData(handle, DATABITS.DB_8, STOPBITS.SB_1, PARITY.P_NONE, BAUDRATE.B9600, 0);
                scm.configureComPortControl(handle, FLOWCONTROL.NONE, 'x', 'x', false, false);
                context = scm.createBlockingIOContext();
 
                while (true) {
 
                    StringBuilder sb = new StringBuilder();
 
                    byte[] dataRead = {};
 
                    for (int x = 0; x < 8; x++) {
                        dataRead = scm.readBytesBlocking(handle, 1, context);
                        if (dataRead != null) {
                            sb.append(bytesToHex(dataRead));
                        }
                    }
 
                    System.out.println("run" + sb.toString());
 
                    Thread.sleep(50);
 
                    synchronized (this) {
                        while (suspended) {
                            wait();
                        }
                        if (stopped) {
                            break;
                        }
                    }
 
                }
            } catch (InterruptedException exc) {
                System.out.println(thrd.getName() + " interrupted.");
                System.out.println("run 1: " + exc.getMessage());
            } catch (IOException ex) {
                Logger.getLogger(ScanRead.class.getName()).log(Level.SEVERE, null, ex);
                System.out.println("run 2: " + ex.getMessage());
            }
        }
 
        public synchronized void stop() {
            System.out.println("stop");
            stopped = true;
            suspended = false;
            notify();
        }
 
        public synchronized void suspend() throws SerialComException {
            suspended = true;
            System.out.println("suspend");
            scm.unblockBlockingIOOperation(context);
            scm.destroyBlockingIOContext(context);
            scm.closeComPort(handle);
        }
 
        public synchronized void resume() throws SerialComException {
            System.out.println("resume");
            suspended = false;
            handle = scm.openComPort(port, true, false, true);
            scm.configureComPortData(handle, DATABITS.DB_8, STOPBITS.SB_1, PARITY.P_NONE, BAUDRATE.B9600, 0);
            scm.configureComPortControl(handle, FLOWCONTROL.NONE, 'x', 'x', false, false);
            context = scm.createBlockingIOContext();
            notify();
        }
 
    }
Si un membre n'ayant pas de carde, je ne veux pas que le code du thread fonctionne, une autre opération doit avoir lieu sur le port série. Il y a un suspend du thread. L'autre processus nécessesitant le port série a lieu et ensuite le résume du thread peut survenir.

Lorsque 'un membre n'ayant pas de carte assigné clique sur un certain bouton, ce code est appelé

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 
    @GetMapping(value = "/members/{memberId}/card")
        public ResponseEntity<Void> updateMemberCardId(@PathVariable("memberId") Long memberId) {
 
            System.out.println("updateCardId");
            StringBuilder sb = new StringBuilder();
            try {
                String port = "/dev/ttyUSB0";
 
 
                scanRead.suspend();
 
                long handle = scm.openComPort(port, true, false, true);
                byte[] dataRead = {};
 
                scm.configureComPortData(handle, SerialComManager.DATABITS.DB_8, SerialComManager.STOPBITS.SB_1, SerialComManager.PARITY.P_NONE, SerialComManager.BAUDRATE.B9600, 0);
                scm.configureComPortControl(handle, SerialComManager.FLOWCONTROL.NONE, 'x', 'x', false, false);
 
                long context = scm.createBlockingIOContext();
 
                for (int x = 0; x < 8; x++) {
                    dataRead = scm.readBytesBlocking(handle, 1, context);
                    if (dataRead != null) {
                        sb.append(bytesToHex(dataRead));
                    }
                }
 
                System.out.println(sb.toString());
 
                scm.unblockBlockingIOOperation(context);
                scm.destroyBlockingIOContext(context);
                scm.closeComPort(handle);
 
                scanRead.resume();
 
                memberService.updateMemberCardId(sb.toString(), memberId);
 
            } catch (IOException ex) {
                Logger.getLogger(MemberController.class.getName()).log(Level.SEVERE, null, ex);
                System.out.println("updated " + ex.getMessage());
            }
            return new ResponseEntity<>(HttpStatus.NO_CONTENT);
        }
Il semble avoir un probleme avec le resume du thread. Ce dernier ne semble part reprendre vie.

Niveau trace, lorsque l'application démarre

**run** est affiché

Je fait appel à cet url: http://localhost:8080/members/1/card No card assigned.

Ces chaines sont affichés

**updatedCardId**
**suspend**

**run 2: I/O operation unblocked !**

Je passe une carte devant le lecteur

Ces chaines sont affichés
**id**
**resume**

Thread ne semble pu fonctionné, car quand j'essaie de scanné une carte de nouveau, rien n'est affiché.

J'obtiens sinon cette autre trace à l'occasion

**run**

**run before read**

**updateCardId**

**suspend**

**updateCardId: before read**

Je scan une carte, rien ne semble se produire
Je scan la carte de nouveau

**updateCardId: after read**

**updateCardId: E00124ABF84CE001**

**resume**

Card id devrait être E004010024ABF84C, il semble avoir comme un lock qui cause un problème de lecture?