Skip to content

Commit

Permalink
Frontend now shares WebSocket and code cleaner
Browse files Browse the repository at this point in the history
  • Loading branch information
Chi-EEE committed Dec 5, 2023
1 parent 06c8e44 commit 2578bce
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 81 deletions.
7 changes: 3 additions & 4 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# TODO List:
- Wrap every endpoint with try-catch to prevent bad actors from crashing the server
- Pass commands from backend to raspberry pi
- Display Lidar data in Svelte

- Pass Lidar data from raspberry pi to backend
- Caleribate the compass
- Authenication to rooms
- Pass commands from backend to raspberry pi
- Display Lidar data in Svelte
47 changes: 30 additions & 17 deletions backend/src/controllers/WebSocketChat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,26 +147,33 @@ void WebSocketChat::handleUserMessage(const drogon::WebSocketConnectionPtr& wsCo
{
auto& user = wsConnPtr->getContextRef<User>();
spdlog::debug("Received a message from user: {} | WebSocketChat::handleUserMessage", wsConnPtr->peerAddr().toIp());
json message_json = json::parse(message);
const std::string message_data = message_json["data"].get<std::string>();
try {
json message_json = json::parse(message);
const std::string message_data = message_json["data"].get<std::string>();

auto& room = RoomManager::instance()->getRoom(user.getChatRoomName());
auto& room = RoomManager::instance()->getRoom(user.getChatRoomName());

json out_json;
out_json["name"] = user.getName();
bool is_command = message_data.rfind("/", 0);
if (is_command) {
this->handleUserCommand(out_json, split(message_data.c_str(), ' '), room);
json out_json;
out_json["name"] = user.getName();
bool is_command = !message_data.rfind("/", 0);
if (is_command) {
this->handleUserCommand(out_json, split(message_data.c_str(), ' '), room);
}
else {
out_json["type"] = "message";
out_json["data"] = message_data;
}
this->chat_rooms.publish(user.getChatRoomName(), out_json.dump());
}
else {
out_json["type"] = "message";
catch (std::exception c) {
spdlog::error("Invalid JSON from {} | WebSocketChat::handleUserMessage", wsConnPtr->peerAddr().toIp());
}
this->chat_rooms.publish(user.getChatRoomName(), out_json.dump());
}

void WebSocketChat::handleUserCommand(json& out_json, std::vector<std::string>& split_string, std::shared_ptr<Room>& room) {
out_json["type"] = "command";
std::string command_type = split_string[0];
command_type.erase(0, 1); // Remove the slash
if (command_type == "move") {
out_json["command"] = "move";
if (split_string.size() == 2) {
Expand Down Expand Up @@ -235,6 +242,12 @@ void WebSocketChat::handleNewConnection(const drogon::HttpRequestPtr& req,
conn->forceClose();
}

/// <summary>
/// room_name
/// type
/// </summary>
/// <param name="req"></param>
/// <param name="conn"></param>
inline void WebSocketChat::handleCreateRequest(const drogon::HttpRequestPtr& req, const drogon::WebSocketConnectionPtr& conn)
{
std::string room_name = req->getParameter("room_name");
Expand All @@ -243,10 +256,6 @@ inline void WebSocketChat::handleCreateRequest(const drogon::HttpRequestPtr& req
conn->forceClose();
return;
}
UserType type = UserType::User;
if (req->getParameter("type") == "car") {
type = UserType::Car;
}
spdlog::info("Creating room {} from {} | WebSocketChat::handleCreateRequest", room_name, req->peerAddr().toIp());
auto user = std::make_shared<User>(
this->chat_rooms.subscribe(room_name,
Expand All @@ -257,7 +266,7 @@ inline void WebSocketChat::handleCreateRequest(const drogon::HttpRequestPtr& req
}),
conn,
room_name,
type
UserType::User
);
auto room = std::make_shared<Room>(user);
RoomManager::instance()->addRoom(room_name, room);
Expand All @@ -273,6 +282,10 @@ inline void WebSocketChat::handleJoinRequest(const drogon::HttpRequestPtr& req,
return;
}
spdlog::info("Joining room {} from {} | WebSocketChat::handleJoinRequest", room_name, req->peerAddr().toIp());
UserType type = UserType::User;
if (req->getParameter("type") == "car") {
type = UserType::Car;
}
auto user = std::make_shared<User>(
this->chat_rooms.subscribe(room_name,
[conn](const std::string& topic,
Expand All @@ -282,7 +295,7 @@ inline void WebSocketChat::handleJoinRequest(const drogon::HttpRequestPtr& req,
}),
conn,
room_name,
UserType::User
type
);
auto room = RoomManager::instance()->getRoom(room_name);
room->addUser(user);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lib/LidarStream.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
const websocket = get(websocket_store);
websocket.addEventListener("message", (event: MessageEvent<any>) => {
websocket!!.addEventListener("message", (event: MessageEvent<any>) => {
const json_data = JSON.parse(event.data);
if (json_data.type == "car") {
points.length = 0;
Expand Down
1 change: 0 additions & 1 deletion frontend/src/routes/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import { dev } from "$app/environment";
import { onMount } from "svelte";
import LidarViewer from "$lib/LidarViewer.svelte";
</script>

<h1>Welcome to SvelteKit</h1>
Expand Down
15 changes: 9 additions & 6 deletions frontend/src/routes/room/[slug]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@
websocket_url_store.set(
`ws://${location.host}/ws/room?request=create&room_name=${room_name}`,
);
websocket_store.subscribe((websocket: WebSocket) => {
websocket.addEventListener("open", (event) => {
websocket_store.subscribe((websocket) => {
websocket!!.addEventListener("open", (event) => {
console.log("Websocket opened");
});
websocket.addEventListener("message", (event: MessageEvent<any>) => {
websocket!!.addEventListener("message", (event: MessageEvent<any>) => {
const json_data = JSON.parse(event.data);
console.log(json_data);
});
});
let message = "";
function sendMessage() {
const websocket: WebSocket = get(websocket_store);
websocket.send(JSON.stringify({ data: message }));
const websocket = get(websocket_store);
websocket!!.send(JSON.stringify({ data: message }));
}
let data: {
Expand All @@ -45,7 +45,10 @@
<h1>This is the Room page</h1>
<h2>Title: {data.room_name}</h2>

<input on:keyup={sendMessage} bind:value={message} />
<input on:keydown={(key_event) => {
if (key.key === "Enter")
sendMessage()
}} bind:value={message} />
<button on:click={sendMessage}>Send</button>

<h1>Hello {data.room_name}!</h1>
Expand Down
5 changes: 2 additions & 3 deletions raspberry_pi/include/global/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ namespace global
std::optional<int> port;

std::string name;

std::string code;
std::string room;
private:
Config()
{
Expand All @@ -61,7 +60,7 @@ namespace global

this->name = config_json["name"].get<std::string>();

this->code = config_json["code"].get<std::string>();
this->room = config_json["room"].get<std::string>();
}
catch (const std::exception& e)
{
Expand Down
2 changes: 1 addition & 1 deletion raspberry_pi/settings/config.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
"host": "localhost",
"port": 8848,
"name": "RaspberryPi",
"code": "1"
"room": "1"
}
15 changes: 8 additions & 7 deletions raspberry_pi/src/car_system/CarSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,23 @@
namespace car_system {
CarSystem::CarSystem(const std::string& websocket_url, std::unique_ptr<LidarDevice> lidar_device, std::unique_ptr<MessagingSystem> messaging_system) : lidar_device(std::move(lidar_device)), messaging_system(std::move(messaging_system))
{
this->initialize(websocket_url);
this->initalize();
}

CarSystem::~CarSystem()
{
this->terminate();
}

void CarSystem::initalize()
{
this->messaging_system->initalize();
}

void CarSystem::run()
{
spdlog::info("Running Car");
this->messaging_system->start();
this->lidar_device->start();
while (true)
{
Expand All @@ -29,15 +35,10 @@ namespace car_system {
}
);
}
this->messaging_system->send(output_json.dump());
this->messaging_system->sendMessage(output_json.dump());
}
}

void CarSystem::initialize(const std::string& websocket_url)
{

}

void CarSystem::terminate()
{
this->lidar_device->terminate();
Expand Down
4 changes: 2 additions & 2 deletions raspberry_pi/src/car_system/CarSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ namespace car_system {
CarSystem(const std::string& websocket_url, std::unique_ptr<LidarDevice> lidar_device, std::unique_ptr<MessagingSystem> messaging_system);
~CarSystem();

void initalize();

void run();
void terminate();

void turn(float angle);
void move(float distance);

private:
void initialize(const std::string& websocket_url);

std::unique_ptr<LidarDevice> lidar_device;
std::unique_ptr<MessagingSystem> messaging_system;
};
Expand Down
60 changes: 30 additions & 30 deletions raspberry_pi/src/car_system/messaging/MessagingSystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,11 @@ namespace car_system::messaging {
{
public:
MessagingSystem(const std::string& websocket_url) : websocket_url(websocket_url) {
this->websocket.start();
bool open = false;
for (int i = 0; i < 3; i++) {
if (this->websocket.getReadyState() == ix::ReadyState::Open) {
open = true;
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(i * 3000));
}
if (!open) {
spdlog::error("Could not connect to websocket");
return;
}
else
{
spdlog::info("Connected to websocket");
}
{
json first_message = { {"type", "car"} };
spdlog::info("Sending first message: {}", first_message.dump());
this->websocket.ping(first_message.dump());
}
};

void initalize() {
};

void initalize()
{
ix::initNetSystem();
this->websocket.setUrl(websocket_url);
this->websocket.setOnMessageCallback([this](const ix::WebSocketMessagePtr& msg)
Expand All @@ -63,20 +42,20 @@ namespace car_system::messaging {
if (message_json["type"] == "command") {
if (message_json["command"] == "turn") {
float angle = message_json["angle"].get<float>();
this->turn_command_signal(
/*this->turn_command_signal(
TurnCommand{
angle
}
);
);*/
spdlog::info("Turning by {} angle", angle);
}
else if (message_json["command"] == "move") {
int speed = message_json["speed"].get<int>();
this->move_command_signal(
/* this->move_command_signal(
MoveCommand{
speed
}
);
);*/
spdlog::info("Moving with {} speed", speed);
}
}
Expand All @@ -101,6 +80,27 @@ namespace car_system::messaging {
);
}

void start()
{
this->websocket.start();
bool open = false;
for (int i = 0; i < 3; i++) {
if (this->websocket.getReadyState() == ix::ReadyState::Open) {
open = true;
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(i * 3000));
}
if (!open) {
spdlog::error("Could not connect to websocket");
return;
}
else
{
spdlog::info("Connected to websocket");
}
}

void terminate() {
this->websocket.stop();
ix::uninitNetSystem();
Expand All @@ -118,8 +118,8 @@ namespace car_system::messaging {
ix::WebSocket websocket;
std::string websocket_url;

nod::signal<void(MoveCommand)> move_command_signal;
nod::signal<void(TurnCommand)> turn_command_signal;
/*nod::signal<void(MoveCommand)> move_command_signal;
nod::signal<void(TurnCommand)> turn_command_signal;*/
};
};

Expand Down
21 changes: 12 additions & 9 deletions raspberry_pi/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@ std::string getWebsocketUrl()
std::optional<int> maybe_port = GET_CONFIG_VALUE(port);
if (maybe_port.has_value())
{
return "ws://" + GET_CONFIG_VALUE(host) + ":" + std::to_string(maybe_port.value()) + "/ws/room?room_name=" + GET_CONFIG_VALUE(code);
return fmt::format("ws://{}:{}/ws/room?request=join&type=car&room_name={}", GET_CONFIG_VALUE(host), maybe_port.value(), GET_CONFIG_VALUE(room));
}
return "ws://" + GET_CONFIG_VALUE(host) + "/ws/room?room_name=" + GET_CONFIG_VALUE(code);
return fmt::format("ws://{}/ws/room?request=join&type=&room_name={}", GET_CONFIG_VALUE(host), GET_CONFIG_VALUE(room));
}

// Car is a global variable so that car.terminate() can be called on exit
std::unique_ptr<CarSystem> car_system_obj;

void terminate() {
car_system_obj->terminate();
spdlog::info("Terminated");
system("pause");
}
//void terminate() {
// car_system_obj->terminate();
// spdlog::info("Terminated");
// system("pause");
//}

int main()
{
Expand All @@ -53,8 +53,11 @@ int main()
std::unique_ptr<LidarDummy> scanner = std::make_unique<LidarDummy>();
// std::unique_ptr<LidarScanner> scanner = std::make_unique<LidarScanner>("COM3");

car_system_obj = std::make_unique<CarSystem>(websocket_url, std::move(scanner));
std::atexit(terminate);
std::unique_ptr<MessagingSystem> messaging_system = std::make_unique<MessagingSystem>(websocket_url);

car_system_obj = std::make_unique<CarSystem>(websocket_url, std::move(scanner), std::move(messaging_system));
//std::atexit(terminate);

car_system_obj->run();

return 0;
Expand Down

0 comments on commit 2578bce

Please sign in to comment.