Start start in frontend! Simulation Query
This commit is contained in:
parent
44e28d8e6b
commit
e698c75309
@ -156,6 +156,16 @@ export const DeleteSignal = (name) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const RunSimulatorSignal = (id) => {
|
||||||
|
const signal = 100;
|
||||||
|
|
||||||
|
return {
|
||||||
|
signal,
|
||||||
|
data: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import HeightPoint from './model/HeightPoint';
|
|||||||
import { RandomHeightPoint } from './helpers/generateRandomHeightPoints'
|
import { RandomHeightPoint } from './helpers/generateRandomHeightPoints'
|
||||||
import ModalWindow from './components/Modal/Modal';
|
import ModalWindow from './components/Modal/Modal';
|
||||||
import { getCustomCookie } from '../Services/Local';
|
import { getCustomCookie } from '../Services/Local';
|
||||||
import useWebsocketConnection, { DeleteSignal, spawnJsonSignal } from '../Services/WebsocketHook';
|
import useWebsocketConnection, { DeleteSignal, spawnJsonSignal, RunSimulatorSignal } from '../Services/WebsocketHook';
|
||||||
import './Dashboard.css';
|
import './Dashboard.css';
|
||||||
|
|
||||||
|
|
||||||
@ -781,7 +781,10 @@ const containsObjectRecursively = (parent, target) => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="btn-group me-2" role="group" aria-label="Third group">
|
<div class="btn-group me-2" role="group" aria-label="Third group">
|
||||||
<button type="button" class="btn btn-info">
|
<button type="button" class="btn btn-info">
|
||||||
<i class="bi-play"/>
|
<i class="bi-play" onClick={() => {
|
||||||
|
sendMessage(RunSimulatorSignal(getCustomCookie("userToken")))
|
||||||
|
|
||||||
|
}}/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -3,7 +3,10 @@ package websocket
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"moxitech/dns/package/math/simulator"
|
"moxitech/dns/package/math/simulator"
|
||||||
|
sim_queue "moxitech/dns/package/simulation"
|
||||||
"moxitech/dns/package/utils/randomizer"
|
"moxitech/dns/package/utils/randomizer"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -49,75 +52,112 @@ func (o *Modulation) MirrorPayloadToSimulationStruct() Modulation {
|
|||||||
return shadow_sim_copy
|
return shadow_sim_copy
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *Modulation) RunSimulator() {
|
// StartNewSimulation - инициирует парсинг и добавление в очередь для обработки симуляции
|
||||||
// // Пример карты высот, замените на настоящие данные
|
func (o *Modulation) StartNewSimulation(timestep int, user_id string) {
|
||||||
// heightData := [][]float64{
|
mapObj := o.Map
|
||||||
// {0, 10, 15, 20},
|
drones := []*simulator.Drone{}
|
||||||
// {5, 15, 25, 30},
|
stations := []*simulator.BaseStation{}
|
||||||
// {10, 20, 35, 40},
|
|
||||||
// {15, 25, 40, 50},
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Определяем карту высот
|
for i, v := range o.Objects {
|
||||||
//
|
if v.Params == nil {
|
||||||
// mapObj := &simulator.Map{
|
continue
|
||||||
// Name: "Example Map",
|
}
|
||||||
// MinBound: [3]float64{-1000, -1000, 0},
|
|
||||||
// MaxBound: [3]float64{1000, 1000, 500},
|
|
||||||
// HeightData: heightData,
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ? mapObj := o.Map
|
|
||||||
|
|
||||||
// // Определяем дронов
|
params := *v.Params
|
||||||
//
|
if v.Type == 1 {
|
||||||
// drones := []*simulator.Drone{
|
// Парсинг параметров для дронов
|
||||||
// {
|
antennaDirection := [3]float64{1, 0, 0} // значение по умолчанию
|
||||||
// ID: 1,
|
if dir, ok := params["antennaDirections"]; ok && dir != "" {
|
||||||
// Name: "Drone 1",
|
directionValues := strings.Split(dir, ",")
|
||||||
// Coords: [3]float64{100, 100, 50},
|
if len(directionValues) == 3 {
|
||||||
// Params: simulator.DroneParams{
|
antennaDirection[0], _ = strconv.ParseFloat(directionValues[0], 64)
|
||||||
// AntennaRadius: 500,
|
antennaDirection[1], _ = strconv.ParseFloat(directionValues[1], 64)
|
||||||
// AntennaDirection: [3]float64{1, 0, 0},
|
antennaDirection[2], _ = strconv.ParseFloat(directionValues[2], 64)
|
||||||
// Waypoints: [][3]float64{{200, 200, 50}},
|
}
|
||||||
// Speed: 10,
|
}
|
||||||
// MeshName: "MeshA",
|
|
||||||
// },
|
antennaRadius := 100.0 // значение по умолчанию
|
||||||
// },
|
if radius, ok := params["antennaRadius"]; ok && radius != "" {
|
||||||
// }
|
antennaRadius, _ = strconv.ParseFloat(radius, 64)
|
||||||
//
|
}
|
||||||
// // Определяем базовые станции
|
|
||||||
//
|
waypoints := [][3]float64{}
|
||||||
// baseStations := []*simulator.BaseStation{
|
if wp, ok := params["wayPoints"]; ok && wp != "" {
|
||||||
// {
|
// Парсинг waypoints, предполагаем, что это строка вида "x1,y1,z1;x2,y2,z2"
|
||||||
// ID: 1,
|
waypointStrings := strings.Split(wp, ";")
|
||||||
// Name: "BaseStation1",
|
for _, waypointStr := range waypointStrings {
|
||||||
// Coords: [3]float64{0, 0, 0},
|
coords := strings.Split(waypointStr, ",")
|
||||||
// Params: simulator.BaseStationParams{
|
if len(coords) == 3 {
|
||||||
// AntennaRadius: 2000,
|
x, _ := strconv.ParseFloat(coords[0], 64)
|
||||||
// AntennaDirection: [3]float64{1, 0, 0},
|
y, _ := strconv.ParseFloat(coords[1], 64)
|
||||||
// },
|
z, _ := strconv.ParseFloat(coords[2], 64)
|
||||||
// },
|
waypoints = append(waypoints, [3]float64{x, y, z})
|
||||||
// }
|
}
|
||||||
//
|
}
|
||||||
// // Создаем симуляцию
|
}
|
||||||
//
|
|
||||||
// sim := &simulator.NetworkSimulation{
|
speed := 0.0
|
||||||
// Map: mapObj,
|
if spd, ok := params["speed"]; ok && spd != "" {
|
||||||
// Drones: drones,
|
speed, _ = strconv.ParseFloat(spd, 64)
|
||||||
// BaseStations: baseStations,
|
}
|
||||||
// TimeStep: 2,
|
|
||||||
// }
|
meshName := ""
|
||||||
//
|
if mesh, ok := params["meshName"]; ok {
|
||||||
// // Запуск симуляции на 300 секунд
|
meshName = mesh
|
||||||
// result_sim := sim.Simulate(300)
|
}
|
||||||
// result := u_sorting.SortMap(result_sim)
|
|
||||||
//
|
drone := simulator.Drone{
|
||||||
// for time, state := range result {
|
ID: i,
|
||||||
// for localstate, f := range state {
|
Name: v.Name,
|
||||||
// fmt.Printf("%v| %v sec :: %v\n", time, localstate, f)
|
Coords: [3]float64{float64(v.Coords[0]), float64(v.Coords[1]), float64(v.Coords[2])},
|
||||||
// }
|
Params: simulator.DroneParams{
|
||||||
// }
|
AntennaRadius: antennaRadius,
|
||||||
|
AntennaDirection: antennaDirection,
|
||||||
|
Waypoints: waypoints,
|
||||||
|
Speed: speed,
|
||||||
|
MeshName: meshName,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
drones = append(drones, &drone)
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.Type == 2 {
|
||||||
|
// Парсинг параметров для базовых станций
|
||||||
|
antennaDirection := [3]float64{1, 0, 0} // значение по умолчанию
|
||||||
|
if dir, ok := params["antennaDirections"]; ok && dir != "" {
|
||||||
|
directionValues := strings.Split(dir, ",")
|
||||||
|
if len(directionValues) == 3 {
|
||||||
|
antennaDirection[0], _ = strconv.ParseFloat(directionValues[0], 64)
|
||||||
|
antennaDirection[1], _ = strconv.ParseFloat(directionValues[1], 64)
|
||||||
|
antennaDirection[2], _ = strconv.ParseFloat(directionValues[2], 64)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
antennaRadius := 200.0 // значение по умолчанию
|
||||||
|
if radius, ok := params["antennaRadius"]; ok && radius != "" {
|
||||||
|
antennaRadius, _ = strconv.ParseFloat(radius, 64)
|
||||||
|
}
|
||||||
|
|
||||||
|
baseStation := simulator.BaseStation{
|
||||||
|
ID: i,
|
||||||
|
Name: v.Name,
|
||||||
|
Coords: [3]float64{float64(v.Coords[0]), float64(v.Coords[1]), float64(v.Coords[2])},
|
||||||
|
Params: simulator.BaseStationParams{
|
||||||
|
AntennaRadius: antennaRadius,
|
||||||
|
AntennaDirection: antennaDirection,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
stations = append(stations, &baseStation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sim := &simulator.NetworkSimulation{
|
||||||
|
Map: &mapObj.Map,
|
||||||
|
Drones: drones,
|
||||||
|
BaseStations: stations,
|
||||||
|
TimeStep: timestep,
|
||||||
|
}
|
||||||
|
sim_queue.AddSimulationTask(*sim, user_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SpawnExampleData создает случайные данные и перезаписывает карту
|
// SpawnExampleData создает случайные данные и перезаписывает карту
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"moxitech/dns/entity/dto"
|
"moxitech/dns/entity/dto"
|
||||||
"moxitech/dns/internal/server/handlers/authorization"
|
"moxitech/dns/internal/server/handlers/authorization"
|
||||||
|
sim_queue "moxitech/dns/package/simulation"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -20,6 +21,8 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func SpawnServer() error {
|
func SpawnServer() error {
|
||||||
|
sim_queue.Start()
|
||||||
|
go sim_queue.InvokeComplete()
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
app.Use(cors.New(cors.Config{
|
app.Use(cors.New(cors.Config{
|
||||||
AllowHeaders: "*",
|
AllowHeaders: "*",
|
||||||
|
@ -230,12 +230,22 @@ func (room *WebsocketRoom) InsertMapFromMongo(name string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RunSimulation запускает симуляцию в горутине
|
// RunSimulation запускает симуляцию в горутине
|
||||||
func (room *WebsocketRoom) RunSimulation(name string) (int, error) {
|
func (room *WebsocketRoom) RunSimulation(message websocket.SignalMessage) (int, error) {
|
||||||
// TODO +NormalizeDataForSimulation()
|
var parsedData struct {
|
||||||
|
UserInvoked string `json:"id"`
|
||||||
|
}
|
||||||
|
// Парсим `data` в структуру
|
||||||
|
err := json.Unmarshal(message.Data, &parsedData)
|
||||||
|
if err != nil {
|
||||||
|
return -1, fmt.Errorf("[insert] error parsing data: %v", err)
|
||||||
|
}
|
||||||
|
if parsedData.UserInvoked == "" {
|
||||||
|
return -1, fmt.Errorf("[insert] Error parse userID: %v", err)
|
||||||
|
}
|
||||||
roomsMutex.Lock()
|
roomsMutex.Lock()
|
||||||
defer roomsMutex.Unlock()
|
defer roomsMutex.Unlock()
|
||||||
room.Modulation.MirrorPayloadToSimulationStruct()
|
room.Modulation.StartNewSimulation(100, parsedData.UserInvoked)
|
||||||
return -1, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NormalizeDataForSimulation - Преобразование данных для отправки в симуляцию
|
// NormalizeDataForSimulation - Преобразование данных для отправки в симуляцию
|
||||||
@ -255,6 +265,7 @@ func (room *WebsocketRoom) WebsocketAction(message []byte) (error, bool) {
|
|||||||
fmt.Printf("[WebsocketAction] %v", err)
|
fmt.Printf("[WebsocketAction] %v", err)
|
||||||
return fmt.Errorf("error parsing occured: %v \n waiting for signal struct", err), false
|
return fmt.Errorf("error parsing occured: %v \n waiting for signal struct", err), false
|
||||||
}
|
}
|
||||||
|
fmt.Println("Run collector")
|
||||||
room.UpdateGroupUptime()
|
room.UpdateGroupUptime()
|
||||||
switch Signal.Signal {
|
switch Signal.Signal {
|
||||||
case 0:
|
case 0:
|
||||||
@ -264,6 +275,7 @@ func (room *WebsocketRoom) WebsocketAction(message []byte) (error, bool) {
|
|||||||
room.InsertObject(Signal)
|
room.InsertObject(Signal)
|
||||||
return nil, true
|
return nil, true
|
||||||
case 2:
|
case 2:
|
||||||
|
fmt.Println("Начата вставка объекта")
|
||||||
room.InsertObject(Signal)
|
room.InsertObject(Signal)
|
||||||
return nil, true
|
return nil, true
|
||||||
case 3:
|
case 3:
|
||||||
@ -287,6 +299,8 @@ func (room *WebsocketRoom) WebsocketAction(message []byte) (error, bool) {
|
|||||||
case 33:
|
case 33:
|
||||||
// SYNC SIGNAL
|
// SYNC SIGNAL
|
||||||
case 100:
|
case 100:
|
||||||
|
fmt.Println("Запуск симуляции : ", Signal)
|
||||||
|
room.RunSimulation(Signal)
|
||||||
case 101:
|
case 101:
|
||||||
// room.StoreMongo(Signal)
|
// room.StoreMongo(Signal)
|
||||||
|
|
||||||
|
60
src/server/package/simulation/sim_queue.go
Normal file
60
src/server/package/simulation/sim_queue.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package sim_queue
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"moxitech/dns/package/math/simulator"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
AddChannel = make(chan simulator.NetworkSimulation)
|
||||||
|
CompleteChannel = make(chan *simulationResult)
|
||||||
|
)
|
||||||
|
|
||||||
|
type simulationResult struct {
|
||||||
|
Sim *simulator.NetworkSimulation
|
||||||
|
UserID string
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddSimulationTask adds a network simulation to the queue and runs it in a goroutine.
|
||||||
|
func AddSimulationTask(sim simulator.NetworkSimulation, userID string) {
|
||||||
|
AddChannel <- sim
|
||||||
|
CompleteChannel <- &simulationResult{Sim: &sim, UserID: userID}
|
||||||
|
}
|
||||||
|
|
||||||
|
// InvokeComplete listens for completed simulations, serializes them to JSON, and sends to a specified endpoint.
|
||||||
|
func InvokeComplete() {
|
||||||
|
for result := range CompleteChannel {
|
||||||
|
go func(result *simulationResult) {
|
||||||
|
jsonData, err := json.Marshal(result.Sim)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error serializing simulation result:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
url := fmt.Sprintf("http://socket:9091/storeEvent?client_id=%s&message=%s", result.UserID, string(jsonData))
|
||||||
|
resp, err := http.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error sending simulation result:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// database.Instance.InsertIntoSimulations(jsonData)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
}(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start starts listening on the channels to manage simulations.
|
||||||
|
func Start() {
|
||||||
|
go func() {
|
||||||
|
for sim := range AddChannel {
|
||||||
|
go runSimulation(sim)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// runSimulation runs a simulation and then sends it to the CompleteChannel.
|
||||||
|
func runSimulation(sim simulator.NetworkSimulation) {
|
||||||
|
sim.Simulate(sim.TimeStep) // Run the simulation for 300 iterations (as an example)
|
||||||
|
CompleteChannel <- &simulationResult{Sim: &sim}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user