mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 13:28:11 +00:00
przywrócenie komunikacji po WS (test)
This commit is contained in:
+47
-5
@@ -47,6 +47,8 @@ import TrainModal from './components/TrainsView/TrainModal.vue';
|
||||
import StorageManager from './managers/storageManager';
|
||||
import { useApiStore } from './store/apiStore';
|
||||
import { Status } from './typings/common';
|
||||
import { Websocket } from './typings/api';
|
||||
import socket from './websocket';
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@@ -86,7 +88,39 @@ export default defineComponent({
|
||||
this.setReleaseURL();
|
||||
this.setupOfflineHandling();
|
||||
|
||||
this.apiStore.setupAPI();
|
||||
this.apiStore.setupStaticAPIData();
|
||||
this.connectToWebsocket();
|
||||
},
|
||||
|
||||
async connectToWebsocket() {
|
||||
this.apiStore.dataStatuses.connection = Status.Data.Loading;
|
||||
|
||||
console.log('ws connecting');
|
||||
|
||||
socket.on('connect_error', (err) => {
|
||||
console.error(`WS connection error: ${err.message}`);
|
||||
|
||||
this.apiStore.dataStatuses.connection = Status.Data.Error;
|
||||
this.apiStore.websocketData = undefined;
|
||||
});
|
||||
|
||||
let timeFrom = Date.now();
|
||||
socket.on('connect', () => {
|
||||
socket.emit('CONNECTION', { version: packageInfo.version }, () => {
|
||||
console.log(`Connection time: ${Date.now() - timeFrom}ms`);
|
||||
});
|
||||
|
||||
console.log('ws connected');
|
||||
});
|
||||
|
||||
socket.on('UPDATE', (data: Websocket.Payload) => {
|
||||
console.log('ws update');
|
||||
|
||||
this.apiStore.websocketData = data;
|
||||
this.apiStore.dataStatuses.connection = Status.Data.Loaded;
|
||||
});
|
||||
|
||||
this.fetchWebsocketData();
|
||||
},
|
||||
|
||||
setupOfflineHandling() {
|
||||
@@ -101,16 +135,24 @@ export default defineComponent({
|
||||
handleOfflineMode() {
|
||||
this.store.isOffline = true;
|
||||
|
||||
this.apiStore.stopActiveDataScheduler();
|
||||
this.apiStore.activeData = undefined;
|
||||
|
||||
this.apiStore.websocketData = undefined;
|
||||
this.apiStore.dataStatuses.connection = Status.Data.Offline;
|
||||
},
|
||||
|
||||
handleOnlineMode() {
|
||||
this.store.isOffline = false;
|
||||
|
||||
this.apiStore.setupAPI();
|
||||
this.apiStore.setupStaticAPIData();
|
||||
this.connectToWebsocket();
|
||||
},
|
||||
|
||||
fetchWebsocketData() {
|
||||
socket.emit('FETCH_DATA', (data: Websocket.Payload) => {
|
||||
console.log('ws fetch data');
|
||||
|
||||
this.apiStore.websocketData = data;
|
||||
this.apiStore.dataStatuses.connection = Status.Data.Loaded;
|
||||
});
|
||||
},
|
||||
|
||||
changeLang(lang: string) {
|
||||
|
||||
+7
-68
@@ -1,9 +1,11 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import http from '../http';
|
||||
import { API } from '../typings/api';
|
||||
import { API, Websocket } from '../typings/api';
|
||||
import axios from 'axios';
|
||||
import { Status } from '../typings/common';
|
||||
import { StationJSONData } from './typings';
|
||||
import { io } from 'socket.io-client';
|
||||
import packageInfo from '../../package.json';
|
||||
|
||||
export const useApiStore = defineStore('apiStore', {
|
||||
state: () => ({
|
||||
@@ -20,43 +22,19 @@ export const useApiStore = defineStore('apiStore', {
|
||||
donatorsData: [] as API.Donators.Response,
|
||||
sceneryData: [] as StationJSONData[],
|
||||
|
||||
activeDataTimeout: undefined as number | undefined
|
||||
websocketData: undefined as Websocket.Payload | undefined
|
||||
|
||||
// activeDataTimeout: undefined as number | undefined
|
||||
}),
|
||||
|
||||
actions: {
|
||||
async setupAPI() {
|
||||
async setupStaticAPIData() {
|
||||
// Static data
|
||||
this.fetchStockInfoData();
|
||||
this.fetchDonatorsData();
|
||||
this.fetchStationsGeneralInfo();
|
||||
|
||||
if (this.activeDataTimeout === undefined) this.startActiveDataScheduler();
|
||||
},
|
||||
|
||||
// async setDataStatuses() {
|
||||
// if (!window.navigator.onLine) {
|
||||
// this.dataStatuses.connection = Status.Data.Offline;
|
||||
// this.dataStatuses.sceneries = Status.Data.Offline;
|
||||
// this.dataStatuses.trains = Status.Data.Offline;
|
||||
// this.dataStatuses.dispatchers = Status.Data.Offline;
|
||||
// this.dataStatuses.timetables = Status.Data.Offline;
|
||||
// }
|
||||
|
||||
// if (!this.activeData?.activeSceneries) {
|
||||
// this.dataStatuses.connection = Status.Data.Loaded;
|
||||
// this.dataStatuses.sceneries = Status.Data.Error;
|
||||
// this.dataStatuses.trains = Status.Data.Error;
|
||||
// this.dataStatuses.dispatchers = Status.Data.Error;
|
||||
|
||||
// return;
|
||||
// }
|
||||
|
||||
// this.dataStatuses.connection = Status.Data.Loaded;
|
||||
// this.dataStatuses.sceneries = Status.Data.Loaded;
|
||||
// this.dataStatuses.trains = !this.activeData.trains ? Status.Data.Warning : Status.Data.Loaded;
|
||||
// this.dataStatuses.dispatchers = Status.Data.Loaded;
|
||||
// },
|
||||
|
||||
async fetchDonatorsData() {
|
||||
try {
|
||||
const response = await http.get<API.Donators.Response>('api/getDonators');
|
||||
@@ -79,45 +57,6 @@ export const useApiStore = defineStore('apiStore', {
|
||||
}
|
||||
},
|
||||
|
||||
async startActiveDataScheduler() {
|
||||
if (!window.navigator.onLine) {
|
||||
this.dataStatuses.connection = Status.Data.Offline;
|
||||
return;
|
||||
}
|
||||
|
||||
if (import.meta.env.VITE_API_MODE === 'mock') {
|
||||
const mockActiveData = await import('../data/mockActiveData.json');
|
||||
this.dataStatuses.connection = Status.Data.Loaded;
|
||||
this.activeData = mockActiveData;
|
||||
|
||||
console.warn('Stacjownik działa w trybie mockowania danych z WS');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const data = (await http.get<API.ActiveData.Response>('api/getActiveData')).data;
|
||||
|
||||
this.activeData = data;
|
||||
this.dataStatuses.connection = Status.Data.Loaded;
|
||||
} catch (error) {
|
||||
this.dataStatuses.connection = Status.Data.Error;
|
||||
console.error('Wystąpił błąd podczas pobierania danych online z API!');
|
||||
} finally {
|
||||
this.activeDataTimeout = window.setTimeout(
|
||||
() => {
|
||||
this.startActiveDataScheduler();
|
||||
},
|
||||
~~(1000 * (Math.random() * (25 - 20) + 25))
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
async stopActiveDataScheduler() {
|
||||
window.clearTimeout(this.activeDataTimeout);
|
||||
this.activeDataTimeout = undefined;
|
||||
},
|
||||
|
||||
async fetchStationsGeneralInfo() {
|
||||
const sceneryData: StationJSONData[] = (await http.get<StationJSONData[]>('api/getSceneries'))
|
||||
.data;
|
||||
|
||||
+3
-94
@@ -34,7 +34,7 @@ export const useMainStore = defineStore('store', {
|
||||
trainList(): Train[] {
|
||||
const apiStore = useApiStore();
|
||||
|
||||
return (apiStore.activeData?.trains ?? [])
|
||||
return (apiStore.websocketData?.activeTrains ?? [])
|
||||
.filter((train) => train.timetable || train.online)
|
||||
.map((train) => {
|
||||
const stock = train.stockString.split(';');
|
||||
@@ -88,9 +88,9 @@ export const useMainStore = defineStore('store', {
|
||||
const apiStore = useApiStore();
|
||||
|
||||
if (state.isOffline) return [];
|
||||
if (!apiStore.activeData?.activeSceneries) return [];
|
||||
if (!apiStore.websocketData?.activeSceneries) return [];
|
||||
|
||||
return apiStore.activeData?.activeSceneries.reduce((list, scenery) => {
|
||||
return apiStore.websocketData?.activeSceneries.reduce((list, scenery) => {
|
||||
if (scenery.isOnline !== 1 && Date.now() - scenery.lastSeen > 1000 * 60 * 2) return list;
|
||||
if (scenery.dispatcherStatus == Status.ActiveDispatcher.UNKNOWN) return list;
|
||||
|
||||
@@ -197,96 +197,5 @@ export const useMainStore = defineStore('store', {
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
async processStationsOnlineInfo(activeData: API.ActiveData.Response) {
|
||||
if (!activeData.activeSceneries) return;
|
||||
|
||||
const onlineSceneries = activeData.activeSceneries.reduce((acc, scenery) => {
|
||||
const savedStation = this.stationList.find((st) => scenery.stationName === st.name);
|
||||
|
||||
if (scenery.isOnline !== 1 && Date.now() - scenery.lastSeen > 1000 * 60 * 2) return acc;
|
||||
if (scenery.dispatcherStatus == Status.ActiveDispatcher.UNKNOWN) return acc;
|
||||
|
||||
const station = this.stationList.find((s) => s.name === scenery.stationName);
|
||||
|
||||
const scheduledTrains = getScheduledTrains(this.trainList, scenery, station?.generalInfo);
|
||||
|
||||
const stationTrains = getStationTrains(
|
||||
this.trainList,
|
||||
scheduledTrains,
|
||||
this.region.id,
|
||||
scenery
|
||||
);
|
||||
|
||||
// Remove checkpoint duplicates
|
||||
const uniqueScheduledTrains = scheduledTrains.reduce(
|
||||
(uniqueList, sTrain) =>
|
||||
uniqueList.find((v) => v.trainId === sTrain.trainId)
|
||||
? uniqueList
|
||||
: [...uniqueList, sTrain],
|
||||
[] as ScheduledTrain[]
|
||||
);
|
||||
|
||||
const dispatcherTimestamp =
|
||||
scenery.dispatcherStatus == Status.ActiveDispatcher.NO_LIMIT
|
||||
? Date.now() + 25500000
|
||||
: scenery.dispatcherStatus > 5
|
||||
? scenery.dispatcherStatus
|
||||
: null;
|
||||
|
||||
const onlineInfo = {
|
||||
name: scenery.stationName,
|
||||
hash: scenery.stationHash,
|
||||
region: scenery.region,
|
||||
maxUsers: scenery.maxUsers,
|
||||
currentUsers: scenery.currentUsers,
|
||||
spawns: parseSpawns(scenery.spawnString),
|
||||
dispatcherName: scenery.dispatcherName,
|
||||
dispatcherRate: scenery.dispatcherRate,
|
||||
dispatcherId: scenery.dispatcherId,
|
||||
dispatcherExp: scenery.dispatcherExp,
|
||||
dispatcherIsSupporter: scenery.dispatcherIsSupporter,
|
||||
scheduledTrains: scheduledTrains,
|
||||
stationTrains: stationTrains,
|
||||
dispatcherStatus: scenery.dispatcherStatus,
|
||||
dispatcherTimestamp: dispatcherTimestamp,
|
||||
|
||||
isOnline: scenery.isOnline == 1,
|
||||
|
||||
scheduledTrainCount: {
|
||||
all: uniqueScheduledTrains.length,
|
||||
confirmed: uniqueScheduledTrains.filter((train) => train.stopInfo.confirmed).length,
|
||||
unconfirmed: uniqueScheduledTrains.filter((train) => !train.stopInfo.confirmed).length
|
||||
}
|
||||
};
|
||||
|
||||
if (savedStation) savedStation.onlineInfo = onlineInfo;
|
||||
else
|
||||
this.stationList.push({
|
||||
name: onlineInfo.name,
|
||||
onlineInfo: onlineInfo
|
||||
});
|
||||
|
||||
acc.push(onlineInfo);
|
||||
|
||||
return acc;
|
||||
}, [] as OnlineScenery[]);
|
||||
|
||||
// Reset online info of already offline sceneries
|
||||
this.stationList
|
||||
.filter(
|
||||
(station) =>
|
||||
station.onlineInfo &&
|
||||
onlineSceneries.findIndex(
|
||||
(os) => os.region == station.onlineInfo!.region && station.name == os.name
|
||||
) != -1
|
||||
)
|
||||
.forEach((station) => (station.onlineInfo = undefined));
|
||||
},
|
||||
|
||||
async changeRegion(region: StoreState['region']) {
|
||||
this.region = region;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -368,3 +368,11 @@ export namespace GithubAPI {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace Websocket {
|
||||
export interface Payload {
|
||||
activeSceneries: API.ActiveSceneries.Response;
|
||||
activeTrains: API.ActiveTrains.Response;
|
||||
connectedSocketCount: number;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { io } from 'socket.io-client';
|
||||
|
||||
const URL =
|
||||
import.meta.env.VITE_WS_MODE === 'development'
|
||||
? 'http://localhost:3001'
|
||||
: 'https://stacjownik.spythere.eu';
|
||||
|
||||
const socket = io(URL, {
|
||||
transports: ['websocket', 'polling'],
|
||||
rememberUpgrade: true,
|
||||
reconnection: true
|
||||
});
|
||||
|
||||
export default socket;
|
||||
Reference in New Issue
Block a user