Как обновить состояние проповеди в ReactJs, когда произошло событие на Сервере - PullRequest
0 голосов
/ 04 мая 2019

У меня есть сервер ExpressJs и внешнее приложение React.В приложении React имеется кнопка-переключатель, которая при изменении состояния выполняет запрос на получение сервера с параметрами запроса в URL-адресе.Сервер обрабатывает запрос и переключает физическое реле (коммутатор) через порт GPIO.

Проблема, с которой я столкнулся, заключается в том, что я также настроил веб-крючок, который запускается из Google Assistant (IFTTT), который переключает состояние переключателя.Это отключает синхронизацию приложения React и фактического состояния коммутатора.Есть ли способ обновить состояние переменной prop во всех открытых веб-сеансах (в приложении React), когда сервер получает запрос через IFTTT.

Экспресс-код сервера

const express = require('express');
const app = express();
const port = process.env.PORT || 5000;

app.listen(port, () => console.log(`Listening on port ${port}`));

app.get('/express_backend', (req, res) => {
  
  //switch the Relay Switch (jname) as per state (jstate):(on, off)
  //then reply to req: res.send({ jstate: sState, jname: sName });
  
  switchController.setSwitch(req.query['jstate'], req.query['jname'],req.query['jaction'], res);

}

Код веб-приложения ReactJs

class ToggleSwitch extends Component {

  componentDidMount() {
    this.postToServer(this.props.id,'','get');
  }

  constructor() {
    super();
    this.state = { checked: false };
    this.handleChange = this.handleChange.bind(this);
  }
  
  callBackendAPI = async (switchName, switchState, switchAction) => {
  
    var getUrl = '/express_backend?jname='+switchName + '&jstate='+switchState + '&jaction='+switchAction;
    const response = await fetch(getUrl,{method: 'get'});
	if (response.status === 200) return await response.json();
  };
  
  postToServer(switchName, switchState, switchAction){
  
    this.callBackendAPI(switchName, switchState, switchAction)
      .then(res => this.setState({checked: (res.jstate === 'true')}))
      .catch(err => console.log(err));

  }
 
  handleChange(checked, event,id) {
    this.postToServer(id,checked,'set');
  }
 
  render() {
    return (
    <div>
    <div style = {{fontSize: '18px', textAlign: 'center', width: '165px', paddingBottom: '5px'}}>{this.props.name}</div>
    <div style = {{height: '50',display: 'flex', alignItems: 'center'}}>
    <Switch
        checked={this.state.checked}
        onChange={this.handleChange}
        height={50}
        width={115}
        className="react-switch"
        id={this.props.id}
      />
	</div>
	</div>
    );
  }
}

Ответы [ 2 ]

0 голосов
/ 12 мая 2019

Решено с помощью Socket.io вместе с http-запросами. Всякий раз, когда сервер получает запрос httpt ifttt, я посылаю широковещательную рассылку для обновления веб-приложения React.

Сервер

const app = require('express')();
const server = require('http').createServer(app);
const io = require('socket.io')(server, {'transports': ['websocket', 'polling']});


io.on('connection', (client) => {
  
  client.on('disconnect', () => {
    console.log('user disconnected');
  })

  app.get('/express_backend', (req, res) => {

    //on request from ifttt broadcast to everyone
    client.broadcast.emit('sendServerUpdate',data);

  });
});

server.listen(port, () => console.log(`Listening on port ${port}`));

Приложение React

import io from 'socket.io-client';
const socket = io({'transports': ['websocket', 'polling']});

subscribeToUpdates(cb) {
  socket.on('sendServerUpdate', data => cb(null, data));
} 

constructor() {
  super();

  this.subscribeToUpdates((err, data) => {
  if(this.props.id === data['jname']) this.setState({ checked: data['jstate']});
});
}
0 голосов
/ 04 мая 2019

Вы пытались использовать веб-сокет с чем-то вроде

npm socket.io

...