UNPKG

3.56 kBJavaScriptView Raw
1import Logger from 'nightingale';
2import { hostname } from 'os';
3import createSocketClient from 'socket.io-client';
4import { serverHost, serverPort, token } from './argv';
5import { getTime as getConfigTime } from './config';
6import { onConfigUpdated } from './manager';
7import * as display from './commands/display';
8import * as screen from './commands/screen';
9import findNetworkInterface from './utils/networkInterface';
10import detectBoard from './utils/detectBoard';
11import { selfUpdate } from './update';
12import { version } from '../package.json';
13
14const logger = new Logger('app:client');
15
16const socket =
17 serverHost &&
18 serverPort &&
19 createSocketClient(`${serverHost}:${serverPort}/raspberry-client`, {
20 reconnectionDelay: 500,
21 reconnectionDelayMax: 120000,
22 timeout: 4000,
23 transports: ['websocket'],
24 });
25
26// wait 5s before connecting, leave the time to start display
27setTimeout(() => {
28 logger.debug('Connecting', { serverHost, serverPort });
29 if (socket) {
30 socket.connect();
31 }
32}, 5000);
33
34const board = detectBoard();
35const rpiVersion = board === 'rpi' && board.info;
36
37const emit = (eventName: string, ...args: Array<any>) => {
38 if (!socket) {
39 logger.warn('cannot emit', { eventName, args });
40 return;
41 }
42
43 logger.debug('emit', { eventName, args });
44 return socket.emit(eventName, ...args);
45};
46
47if (socket) {
48 socket.on('connect_error', err =>
49 logger.error('connect error', { serverHost, serverPort, errMessage: err.message }),
50 );
51 socket.on('reconnect_error', err =>
52 logger.debug('reconnect error', { serverHost, serverPort, err }),
53 );
54
55 socket.on('disconnect', () => logger.warn('disconnected'));
56
57 socket.on('reconnect', () => logger.success('reconnected'));
58
59 socket.on('connect', () => {
60 logger.success('connected');
61
62 const networkInterface = findNetworkInterface();
63 const screenState = screen.getCurrentScreenState();
64 emit('hello', {
65 configTime: getConfigTime(),
66 version,
67 token,
68 userId: token, // deprecated
69 screenState, // deprecated
70 ...networkInterface,
71 hostname: hostname(),
72 rpiVersion,
73 board,
74 screen: {
75 state: screenState,
76 screens: screen.getCurrentScreens(),
77 },
78 availableDisplays: display.availableDisplays,
79 });
80 });
81
82 socket.on('updateConfig', onConfigUpdated);
83 socket.on('changeConfig', onConfigUpdated);
84
85 socket.on('selfUpdate', () => selfUpdate());
86
87 socket.on('action', (action: string) => {
88 logger.info('received action', { action });
89 switch (action) {
90 case 'self-upgrade':
91 case 'self-update':
92 case 'selfUpdate':
93 return selfUpdate();
94
95 case 'screen-off':
96 return screen.off();
97 case 'screen-on':
98 return screen.on();
99
100 case 'refresh':
101 return display.refresh();
102 }
103
104 logger.warn(`unknown action: ${action}`);
105 });
106
107 socket.on('screenshot', () => {
108 logger.info('screenshot');
109 const buffer = screen.screenshot();
110 if (!buffer) {
111 return;
112 }
113
114 logger.info('send screenshot');
115 socket.emit('screenshot', { image: true, buffer }, () => {
116 logger.info('screenshot callback');
117 });
118 });
119}
120
121export const sendUpdate = (data: Object): void => {
122 emit('update', data);
123};
124
125export function close(): Promise<any> | void {
126 if (!socket || !socket.connected) {
127 return;
128 }
129
130 return new Promise(resolve => {
131 logger.info('Closing...');
132 socket.once('disconnect', () => {
133 logger.info('Closed');
134 resolve();
135 });
136 socket.close();
137 });
138}