@@ -5,6 +5,30 @@ let remoteBuzzerClient;
55let rotaryController ;
66let buttonController ;
77
8+ // Quick reachability probe so we don't start socket.io polling when the server is down.
9+ // Uses XMLHttpRequest to avoid Node fetch lint issues; runs in the browser.
10+ const checkRemoteBuzzerReachable = ( baseUrl , timeoutMs = 3000 ) =>
11+ new Promise ( ( resolve ) => {
12+ const xhr = new XMLHttpRequest ( ) ;
13+ const timeout = setTimeout ( ( ) => {
14+ xhr . abort ( ) ;
15+ resolve ( false ) ;
16+ } , timeoutMs ) ;
17+
18+ xhr . onerror = ( ) => {
19+ clearTimeout ( timeout ) ;
20+ resolve ( false ) ;
21+ } ;
22+
23+ xhr . onload = ( ) => {
24+ clearTimeout ( timeout ) ;
25+ resolve ( true ) ;
26+ } ;
27+
28+ xhr . open ( 'GET' , baseUrl + '/socket.io/?EIO=4&transport=polling&t=' + Date . now ( ) , true ) ;
29+ xhr . send ( ) ;
30+ } ) ;
31+
832// eslint-disable-next-line no-unused-vars
933function initRemoteBuzzerFromDOM ( ) {
1034 photoboothTools . console . logDev (
@@ -18,101 +42,123 @@ function initRemoteBuzzerFromDOM() {
1842 */
1943
2044 remoteBuzzerClient = ( function ( ) {
45+ photoboothTools . console . log ( 'remoteBuzzerClient init' ) ;
46+
2147 let ioClient ;
48+ let serverReachable = false ;
2249 const api = { } ;
2350
2451 api . enabled = function ( ) {
2552 return config . remotebuzzer . usebuttons || config . remotebuzzer . userotary ;
2653 } ;
2754
55+ api . connected = function ( ) {
56+ return serverReachable && ! ! ioClient ;
57+ } ;
58+
2859 api . init = function ( ) {
2960 if ( ! this . enabled ( ) ) {
3061 return ;
3162 }
3263
3364 if ( config . remotebuzzer . serverip ) {
34- ioClient = io (
35- window . location . protocol + '//' + config . remotebuzzer . serverip + ':' + config . remotebuzzer . port
36- ) ;
37- photoboothTools . console . logDev (
38- 'Remote buzzer connecting to ' +
39- window . location . protocol +
40- '//' +
41- config . remotebuzzer . serverip +
42- ':' +
43- config . remotebuzzer . port
44- ) ;
45-
46- ioClient . on ( 'photobooth-socket' , function ( data ) {
47- switch ( data ) {
48- case 'start-picture' :
49- buttonController . takePicture ( ) ;
50- break ;
51-
52- case 'start-collage' :
53- buttonController . takeCollage ( ) ;
54- break ;
55-
56- case 'start-custom' :
57- buttonController . takeCustom ( ) ;
58- break ;
59-
60- case 'start-video' :
61- buttonController . takeVideo ( ) ;
62- break ;
63-
64- case 'collage-next' :
65- // Need to handle collage process in button handler
66- if ( buttonController . waitingToProcessCollage ) {
67- buttonController . processCollage ( ) ;
68- } else {
69- buttonController . takeCollageNext ( ) ;
65+ const baseUrl =
66+ window . location . protocol + '//' + config . remotebuzzer . serverip + ':' + config . remotebuzzer . port ;
67+
68+ checkRemoteBuzzerReachable ( baseUrl )
69+ . then ( ( reachable ) => {
70+ if ( ! reachable ) {
71+ photoboothTools . console . log (
72+ 'Remote buzzer server not reachable at ' + baseUrl + ' - skipping connection.'
73+ ) ;
74+ return ;
75+ }
76+
77+ photoboothTools . console . log (
78+ 'Remote buzzer server is reachable at ' + baseUrl + ' - skipping connection.'
79+ ) ;
80+
81+ serverReachable = true ;
82+ ioClient = io ( baseUrl ) ;
83+ photoboothTools . console . logDev ( 'Remote buzzer connecting to ' + baseUrl ) ;
84+
85+ ioClient . on ( 'photobooth-socket' , function ( data ) {
86+ switch ( data ) {
87+ case 'start-picture' :
88+ buttonController . takePicture ( ) ;
89+ break ;
90+
91+ case 'start-collage' :
92+ buttonController . takeCollage ( ) ;
93+ break ;
94+
95+ case 'start-custom' :
96+ buttonController . takeCustom ( ) ;
97+ break ;
98+
99+ case 'start-video' :
100+ buttonController . takeVideo ( ) ;
101+ break ;
102+
103+ case 'collage-next' :
104+ // Need to handle collage process in button handler
105+ if ( buttonController . waitingToProcessCollage ) {
106+ buttonController . processCollage ( ) ;
107+ } else {
108+ buttonController . takeCollageNext ( ) ;
109+ }
110+ break ;
111+
112+ case 'print' :
113+ buttonController . print ( ) ;
114+ break ;
115+
116+ case 'rotary-cw' :
117+ rotaryController . focusNext ( ) ;
118+ break ;
119+
120+ case 'rotary-ccw' :
121+ rotaryController . focusPrev ( ) ;
122+ break ;
123+
124+ case 'rotary-btn-press' :
125+ rotaryController . click ( ) ;
126+ break ;
127+
128+ case 'start-move2usb' :
129+ buttonController . move2usb ( ) ;
130+ break ;
131+
132+ default :
133+ break ;
70134 }
71- break ;
72-
73- case 'print' :
74- buttonController . print ( ) ;
75- break ;
76-
77- case 'rotary-cw' :
78- rotaryController . focusNext ( ) ;
79- break ;
80-
81- case 'rotary-ccw' :
82- rotaryController . focusPrev ( ) ;
83- break ;
84-
85- case 'rotary-btn-press' :
86- rotaryController . click ( ) ;
87- break ;
88-
89- case 'start-move2usb' :
90- buttonController . move2usb ( ) ;
91- break ;
92-
93- default :
94- break ;
95- }
96- } ) ;
97-
98- ioClient . on ( 'connect_error' , function ( ) {
99- photoboothTools . console . log (
100- 'ERROR: Remote buzzer client unable to connect to Remote buzzer Server - please ensure Remote buzzer server is running on ' +
101- config . remotebuzzer . serverip +
102- '. Set Photobooth loglevel to 1 (or above) to create log file for debugging.'
103- ) ;
104- } ) ;
105-
106- ioClient . on ( 'connect' , function ( ) {
107- photoboothTools . console . logDev (
108- 'Remote buzzer client successfully connected to Remote buzzer Server.'
109- ) ;
110- } ) ;
111-
112- buttonController . init ( ) ;
113- rotaryController . init ( ) ;
114-
115- rotaryController . focusSet ( '.stage[data-stage="start"]' ) ;
135+ } ) ;
136+
137+ ioClient . on ( 'connect_error' , function ( ) {
138+ photoboothTools . console . log (
139+ 'ERROR: Remote buzzer client unable to connect to Remote buzzer Server - please ensure Remote buzzer server is running on ' +
140+ config . remotebuzzer . serverip +
141+ '. Set Photobooth loglevel to 1 (or above) to create log file for debugging.'
142+ ) ;
143+ } ) ;
144+
145+ ioClient . on ( 'connect' , function ( ) {
146+ photoboothTools . console . logDev (
147+ 'Remote buzzer client successfully connected to Remote buzzer Server.'
148+ ) ;
149+ } ) ;
150+
151+ buttonController . init ( ) ;
152+ rotaryController . init ( ) ;
153+
154+ rotaryController . focusSet ( '.stage[data-stage="start"]' ) ;
155+ } )
156+ . catch ( ( ) => {
157+ serverReachable = false ;
158+ photoboothTools . console . log (
159+ 'Remote buzzer server not reachable at ' + baseUrl + ' - skipping connection.'
160+ ) ;
161+ } ) ;
116162 } else {
117163 photoboothTools . console . log (
118164 'ERROR: Remote buzzer client unable to connect - Remote buzzer Server IP not defined in photobooth config!'
@@ -175,6 +221,11 @@ function initRemoteBuzzerFromDOM() {
175221 } ;
176222
177223 api . emitToServer = function ( cmd , photoboothAction ) {
224+ if ( ! this . connected ( ) ) {
225+ photoboothTools . console . logDev ( 'Skip emitting remote buzzer command; server not connected.' ) ;
226+ return ;
227+ }
228+
178229 switch ( cmd ) {
179230 case 'start-picture' :
180231 ioClient . emit ( 'photobooth-socket' , 'start-picture' ) ;
0 commit comments