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
My thread code
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(); } }
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.
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(); } }
Lorsque 'un membre n'ayant pas de carte assigné clique sur un certain bouton, ce code est appelé
Il semble avoir un probleme avec le resume du thread. Ce dernier ne semble part reprendre vie.
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); }
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?
Partager