import Context from './DevicesContext' import { HubConnectionBuilder } from '@microsoft/signalr'; import DeviceService from '../common/DeviceService'; import C from '../common/Constants' import React, { Component } from 'react' const hub_url = '/hubs/devices'; export default class DevicesContextProvider extends Component { constructor(props) { super(props); const handlers = {}; for (var property in C) { handlers[C[property]] = []; }; this.state = { hubConnection: null, devices: [], heatmapPoints: [], handlers: handlers, }; } addHandler = (methodName, handler) => { const updatedHandlers = this.state.handlers; updatedHandlers[methodName].push(handler); //console.log("Added '" + methodName + "' handler."); this.setState({ handlers: updatedHandlers }); } removeHandler = (methodName, handler) => { const updatedHandlers = this.state.handlers; var index = updatedHandlers[methodName].findIndex((h => h === handler)); if (index > -1) { updatedHandlers[methodName].splice(index, 1); //console.log("Removed '" + methodName + "' handler."); } this.setState({ handlers: updatedHandlers }); } updateDevice = (id) => { this.updateDeviceInternal(id); } updateAllDevices = () => { this.updateAllDevicesInternal(); } invokeHandlers(methodName, context) { this.state.handlers[methodName].forEach(function (handler) { handler(context); }); } updateAllDevicesInternal(service = null) { if (service === null) { service = new DeviceService(); } service.getall().then(result => { this.setState({ devices: result }); this.invokeHandlers(C.update_all_method_name, null); }).catch(ex => { console.log(ex); }); } updateDeviceInternal(id, service = null) { if (service === null) { service = new DeviceService(); } service.getdevice(id).then(result => { const updatedDevices = [...this.state.devices]; var index = updatedDevices.findIndex((d => d.id == id)); if (index > -1) { updatedDevices[index] = result; } else { updatedDevices.push(result); } this.setState({ devices: updatedDevices }); this.invokeHandlers(C.update_method_name, result); }).catch(ex => console.log("Device update failed.", ex)); } componentDidMount() { const service = new DeviceService(); this.updateAllDevicesInternal(service); const newConnection = new HubConnectionBuilder() .withUrl(hub_url) .withAutomaticReconnect() .build(); this.setState({ hubConnection: newConnection }); newConnection.start() .then(_ => { console.log('Devices hub Connected!'); newConnection.on(C.probability_method_name, (messages) => { //console.log(method_name + " recieved: [id: " + id + ", date: " + date + ", prob: " + prob + "]"); const newPoints = []; for (var message of messages) { var device = this.state.devices.filter(function (x) { return x.id === message.deviceId })[0] var newPoint = { deviceId: device.id, lat: device.coordinates.latitude, lng: device.coordinates.longitude, prob: message.probability, date: new Date(message.date) }; newPoints.push(newPoint); } this.setState({ heatmapPoints: this.state.heatmapPoints.concat(newPoints) }); this.invokeHandlers(C.probability_method_name, newPoints); }); newConnection.on(C.update_all_method_name, () => { this.updateAllDevicesInternal(service); }); newConnection.on(C.update_method_name, (id) => this.updateDeviceInternal(id, service)); }).catch(e => console.log('Devices hub Connection failed: ', e)); } componentWillUnmount() { if (this.state.hubConnection != null) { this.state.hubConnection.off(C.probability_method_name); this.state.hubConnection.off(C.update_all_method_name); this.state.hubConnection.off(C.update_method_name); console.log('Devices hub Disconnected!'); } } render() { return ( {this.props.children} ); }; }