Я пытаюсь создать API на сервере, используя express-ws
для удаленного управления Raspberry-pi, запуска и остановки программы на pi для безопасного отключения.
Идея состоит в том, чтопользователь нажимал кнопку (запуск / остановка) на клиенте браузера, которая отправляла бы запрос GET
к API, инициирующий событие для отправки сообщения через веб-сокет на пи. Pi запускает python, используя библиотеку websockets
для подключения и получения сообщений от API. Сервер использует следующий код:
const express = require('express');
const router = express.Router();
const events = require('events');
const eventEmitter = new events.EventEmitter();
router.get('/setDevice/:status', function(req, res){
const status = req.params.status;
eventEmitter.emit(status);
res.send(status);
});
router.ws('/deviceStatus', function(ws, req){
ws.on('open', function(){
ws.send("Connected!");
console.log('newConnection');
});
eventEmitter.on('start', function(){
ws.send("start");
});
eventEmitter.on('stop', function(){
ws.send("stop")
});
ws.on('close', function(){
console.log("connection closed");
});
});
module.exports=router;
Я могу успешно подключить pi к серверу и получать соответствующие сообщения всякий раз, когда достигается конечная точка GET
, но если я отключаюсь и повторно подключаю pi с сервераон больше не будет получать сообщения, и я получаю следующую ошибку от сервера:
<code><body>
<h1>WebSocket is not open: readyState 3 (CLOSED)</h1>
<h2></h2>
<pre>Error: WebSocket is not open: readyState 3 (CLOSED)
at WebSocket.send (C:\Projects\BLE_webapp\api\node_modules\ws\lib\websocket.js:314:19)
at EventEmitter.<anonymous> (C:\Projects\BLE_webapp\api\routes\socketRoutes.js:21:12)
at EventEmitter.emit (events.js:203:15)
at C:\Projects\BLE_webapp\api\routes\socketRoutes.js:11:18
at Layer.handle [as handle_request] (C:\Projects\BLE_webapp\api\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Projects\BLE_webapp\api\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (C:\Projects\BLE_webapp\api\node_modules\express\lib\router\route.js:112:3)
at Layer.handle [as handle_request] (C:\Projects\BLE_webapp\api\node_modules\express\lib\router\layer.js:95:5)
at C:\Projects\BLE_webapp\api\node_modules\express\lib\router\index.js:281:22
at param (C:\Projects\BLE_webapp\api\node_modules\express\lib\router\index.js:354:14)
Если я перезагружу сервер и снова подключу пи, все снова в порядке. Похоже, ошибка указывает на то, что сервер пытается попасть в закрытый веб-сокет, а не в новый. Есть ли способ сказать express
, чтобы удалить старое соединение при закрытии и сосредоточиться только на живых (ых)?
Примечание: В конце концов, я хочу расширить это для поддержки нескольких пи с возможностью пользователявключить / выключить определенные устройства. Я не уверен, есть ли решения, которые лучше позволяют это сделать. Я еще не проверял это на нескольких письмах, но у меня такое чувство, что это все еще будет проблемой.