Skip to content

Commit

Permalink
BROKEN VERSION: Still working on websocket weirdness
Browse files Browse the repository at this point in the history
  • Loading branch information
connornishijima committed May 31, 2024
1 parent 1966e98 commit d9a8828
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 48 deletions.
87 changes: 57 additions & 30 deletions data/js/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ var device_ip = null;
var last_event_time = null;
var websockets_open = false;
var queued_packets = [];
var processing_command_queue = false;

var system_state = {
"stats": {},
Expand Down Expand Up @@ -176,6 +177,7 @@ function parse_emotiscope_packet(packet){

document.getElementById("device_nickname").innerHTML = device_ip;
document.getElementById("device_nickname").innerHTML = "FPS CPU: "+parseInt(system_state.stats.fps_cpu)+" GPU: "+parseInt(system_state.stats.fps_gpu)+" TEMP: "+parseInt(system_state.stats.cpu_temp)+"C";
document.getElementById("device_nickname").innerHTML = "WS CLIENTS: "+parseInt(system_state.stats.ws_clients);
}

function parse_event(message){
Expand Down Expand Up @@ -300,30 +302,44 @@ function check_event_timeout(){

function send_queued_packets(){
for( let i = 0; i < queued_packets.length; i++ ){
console.log("TX: " + queued_packets[i]);
ws.send(queued_packets[i]);
if(queued_packets[i].sent == false){
console.log("TX: " + queued_packets[i].message);
try{
ws.send(queued_packets[i].message);
queued_packets[i].sent = true;
}
catch(e){
console.log("ERROR SENDING QUEUED WEBSOCKETS: "+e);
}
}
}
queued_packets = [];

// Remove all sent packets
queued_packets = queued_packets.filter(packet => packet.sent == false);
}

function wstx(message){
if(websockets_open == true){
ws.send(message);
console.log("TX: " + message);
}
else{
queued_packets.push(message);
console.log("TX QUEUED: " + message);
}
queued_packets.push(
{
"message":message,
"sent":false
}
);
console.log("TX QUEUED: " + message);

process_command_queue();
}

function open_websockets_connection(){
if(websockets_open == false){
if(ws == null || ws.readyState == 3){
console.log("OPENING WEBSOCKETS");
websockets_open = true;

ws = new WebSocket("ws://"+device_ip+":80/ws");
ws.onopen = function(){
websockets_open = true;
send_queued_packets();
console.log("WEBSOCKETS OPEN");
send_queued_packets();

};
ws.onmessage = function(event){
console.log("RX: " + event.data);
Expand All @@ -338,33 +354,38 @@ function open_websockets_connection(){
websockets_open = false;
}
}
else{
console.log("WEBSOCKETS ALREADY OPEN");
send_queued_packets();
}
}

function close_websockets_connection(){
if(websockets_open == true){
try{
ws.close();
}
catch(e){
console.log("ERROR CLOSING WEBSOCKETS: "+e);
}

websockets_open = false;
websockets_open = false;
try{
ws.close();
}
catch(e){
console.log("ERROR CLOSING WEBSOCKETS: "+e);
}
}

function handle_up_event(event) {
console.log("FINGER UP");

setTimeout(function(){
close_websockets_connection();
}, 250);
//console.log("FINGER UP");
wstx("touch_end");
}

function handle_down_event(event) {
console.log("FINGER DOWN");
//console.log("FINGER DOWN");
wstx("touch_start");
}

open_websockets_connection();
function process_command_queue(){
console.log("queued packets: "+queued_packets.length);
let queue_length = queued_packets.length;
if(queue_length > 0){
open_websockets_connection();
}
}

(function() {
Expand All @@ -378,6 +399,12 @@ function handle_down_event(event) {

connect_to_emotiscope();

//setInterval(function(){
// open_websockets_connection();
//}, 1000);

console.log("REGISTERING MOUSE/TAP EVENTS");

// Add event listeners for mousedown and touchstart events
document.addEventListener('mousedown', handle_down_event);
document.addEventListener('touchstart', handle_down_event);
Expand Down
15 changes: 8 additions & 7 deletions platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,22 @@
; https://docs.platformio.org/page/projectconf.html

[env:esp32-s3-devkitc-1]
platform = https://github.com/platformio/platform-espressif32.git#develop
platform_packages =
platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0
platformio/framework-arduinoespressif32-libs @ https://github.com/espressif/esp32-arduino-libs.git#idf-release/v5.1
platform = [email protected]
platform_packages=
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#3.0.0
framework-arduinoespressif32-libs @ https://github.com/espressif/arduino-esp32/releases/download/3.0.0/esp32-arduino-libs-3.0.0.zip

board = esp32-s3-devkitc-1
framework = arduino
lib_deps =
https://github.com/hoeken/PsychicHttp
https://github.com/hoeken/PsychicHttp @ ^1.1.0
upload_speed = 2000000
;upload_port = COM10
;upload_port = COM10
monitor_speed = 2000000
;monitor_port = COM10
monitor_filters =
;debug
send_on_enter
send_on_enter
;esp32_exception_decoder

debug_tool = esp-builtin
Expand Down
4 changes: 2 additions & 2 deletions src/EMOTISCOPE_FIRMWARE.ino
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,13 @@
// One core to run audio and web server ---------------------------------------
void loop() {
run_cpu(); // (cpu_core.h)
run_web(); // (web_core.h)
}

// One core to run graphics ---------------------------------------------------
void loop_gpu(void *param) {
for (;;) {
run_gpu(); // (gpu_core.h)
run_web(); // (web_core.h)
}
}

Expand All @@ -133,5 +133,5 @@ void setup() {
init_system();

// Start the second core as a dedicated webserver
(void)xTaskCreatePinnedToCore(loop_gpu, "loop_gpu", 4096, NULL, 0, NULL, 0);
(void)xTaskCreatePinnedToCore(loop_gpu, "loop_gpu", 8192, NULL, 0, NULL, 0);
}
12 changes: 5 additions & 7 deletions src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,6 @@ struct tempo {
uint32_t block_size;
};

// Clients are like Players in the web app. Like a video game console, they
// are plugged into one of four sockets
struct websocket_client {
int socket;
uint32_t last_ping;
};

// Stores the state of capacitive touch pins
struct touch_pin {
uint8_t pin;
Expand All @@ -145,6 +138,11 @@ struct touch_pin {
float touch_history[50]; // 5 seconds at 10 FPS
};

struct websocket_client {
int socket;
uint32_t last_proof_of_life;
};

// union that stores the value of a config item
union config_value {
uint32_t u32;
Expand Down
6 changes: 6 additions & 0 deletions src/web_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ void run_web() {
configuration_changed = false;
}

static uint32_t last_websocket_client_test_ms = 0;
if (t_now_ms - last_websocket_client_test_ms >= 100) {
last_websocket_client_test_ms = t_now_ms;
test_clients();
}

// Broadcast the current state to all clients
static uint32_t last_state_broadcast_ms = 0;
if (t_now_ms - last_state_broadcast_ms >= 250) {
Expand Down
78 changes: 76 additions & 2 deletions src/wireless.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define MAX_HTTP_REQUEST_ATTEMPTS (8) // Define the maximum number of retry attempts
#define INITIAL_BACKOFF_MS (1000) // Initial backoff delay in milliseconds
#define MAX_NETWORK_CONNECT_ATTEMPTS (3)
#define MAX_WEBSOCKETS_CLIENTS (4)

#define DISCOVERY_SERVER_URL "https://app.emotiscope.rocks/discovery/"

Expand All @@ -21,6 +22,8 @@ int16_t connection_status = -1;

uint8_t network_connection_attempts = 0;

websocket_client clients[MAX_WEBSOCKETS_CLIENTS];

void reboot_into_wifi_config_mode() {
preferences.putBool("CONFIG_TRIG", true);
delay(100);
Expand Down Expand Up @@ -173,6 +176,16 @@ void broadcast_emotiscope_state(){
sprintf(temp_buffer, "|heap|%lu", esp_get_free_heap_size());
strcat(output_string, temp_buffer);

uint16_t current_ws_clients = 0;
for(uint16_t i = 0; i < MAX_WEBSOCKETS_CLIENTS; i++){
if(clients[i].last_proof_of_life != 0){
current_ws_clients++;
}
}
memset(temp_buffer, 0, 128);
sprintf(temp_buffer, "|ws_clients|%lu", current_ws_clients);
strcat(output_string, temp_buffer);

//printf("TX: %s\n", output_string);
event_source.send(output_string);

Expand Down Expand Up @@ -310,16 +323,64 @@ void parse_emotiscope_packet(char* command, PsychicWebSocketRequest *request){
}
}

bool add_client(PsychicWebSocketClient *client){
bool found_slot = false;
for(uint16_t i = 0; i < MAX_WEBSOCKETS_CLIENTS; i++){
if(clients[i].last_proof_of_life == 0){
clients[i].socket = client->socket();
clients[i].last_proof_of_life = t_now_ms;
found_slot = true;
break;
}
}

return found_slot;
}

void remove_client(int socket){
for(uint16_t i = 0; i < MAX_WEBSOCKETS_CLIENTS; i++){
if(clients[i].socket == socket){
clients[i].last_proof_of_life = 0;
clients[i].socket = 0;
break;
}
}
}

void test_clients(){
for(uint16_t i = 0; i < MAX_WEBSOCKETS_CLIENTS; i++){
if(clients[i].last_proof_of_life != 0){
if(t_now_ms - clients[i].last_proof_of_life >= 200){
printf("Client #%i has not sent proof of life in 200ms, closing.\n", clients[i].socket);
PsychicWebSocketClient *client = websocket_handler.getClient(clients[i].socket);
if(client != NULL){
client->close();
}
else{
printf("ERROR: Client not found in test_clients\n");
}

clients[i].last_proof_of_life = 0;
clients[i].socket = 0;
}
}
}
}

void init_web_server() {
const char *local_hostname = "emotiscope";
if (MDNS.begin(local_hostname) == true) {
MDNS.addService("http", "tcp", 80);
}
else{
println("Error starting mDNS");
printf("Error starting mDNS\n");
}

server.config.max_uri_handlers = 40; // maximum number of .on() calls
memset(clients, 0, sizeof(clients));

server.config.stack_size = 8192; // stack size for each thread
server.config.max_uri_handlers = 20; // maximum number of .on() calls
server.config.max_open_sockets = 8; // maximum number of open sockets

server.listen(80);

Expand All @@ -338,12 +399,23 @@ void init_web_server() {

websocket_handler.onOpen([](PsychicWebSocketClient *client) {
printf("[socket] connection #%i connected from %s\n", client->socket(), client->remoteIP().toString().c_str());

if( add_client( client ) == false ){
printf( "Client not accepted, too many clients.\n" );
client->close();
}
});

websocket_handler.onFrame([](PsychicWebSocketRequest *request, httpd_ws_frame *frame) {
// printf("[socket] #%d sent: %s\n", request->client()->socket(), (char*)frame->payload);
httpd_ws_type_t frame_type = frame->type;

for(uint16_t i = 0; i < MAX_WEBSOCKETS_CLIENTS; i++){
if(clients[i].socket == request->client()->socket()){
clients[i].last_proof_of_life = t_now_ms;
}
}

// If it's text, it might be a command
if (frame_type == HTTPD_WS_TYPE_TEXT) {
char* command = (char*)frame->payload;
Expand All @@ -365,9 +437,11 @@ void init_web_server() {

websocket_handler.onClose([](PsychicWebSocketClient *client) {
printf("[socket] connection #%i closed from %s\n", client->socket(), client->remoteIP().toString().c_str());
remove_client(client->socket());
});

server.on("/ws", &websocket_handler);
//server.on("/ws")->attachHandler(&websocket_handler);

server.on("/mac", HTTP_GET, [](PsychicRequest *request) {
return request->reply(mac_str);
Expand Down

0 comments on commit d9a8828

Please sign in to comment.