Mongoose server

Linux specific forum
wombats
Enthusiast
Enthusiast
Posts: 662
Joined: Thu Dec 29, 2011 5:03 pm

Mongoose server

Post by wombats »

Hi,

I'm trying to use Mongoose with PB. I'm trying to put it into a DLL/dylib/shared object, which works on Windows and macOS, but crashes on Linux. Has anyone had any experience with it and might know what I'm doing wrong on Linux?

PB file

Code: Select all

Global quit

Prototype.i pStartServer()
Prototype.i pUpdateServer()
Prototype.i pShutdownServer()

If OpenLibrary(0, "libmongoose.so")

  StartServer.pStartServer = GetFunction(0, "StartServer")
  UpdateServer.pUpdateServer = GetFunction(0, "UpdateServer")
  ShutdownServer.pShutdownServer = GetFunction(0, "ShutdownServer")
  
  If StartServer()
    
    OpenWindow(0, 0, 0, 320, 240, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
    
    AddWindowTimer(0, 0, 500)
    
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_Timer
          UpdateServer()
        Case #PB_Event_CloseWindow
          quit = 1
      EndSelect
    Until quit
    
  EndIf
  
EndIf
main.c

Code: Select all

// Adapted from https://github.com/cesanta/mongoose/blob/master/examples/desktop-server/main.c (Copyright (c) 2020 Cesanta Software Limited)

#include "main.h"
#include "mongoose/mongoose.h"

static const char* s_web_root_dir = ".";
static const char* s_listening_address = "http://0.0.0.0:8000";

struct mg_mgr mgr;
struct mg_connection* c;

static void cb(struct mg_connection* c, int ev, void* ev_data, void* fn_data) {
    if (ev == MG_EV_HTTP_MSG) {
        mg_http_serve_dir(c, ev_data, s_web_root_dir);
    }
    (void)fn_data;
}

int StartServer() {
    mg_mgr_init(&mgr);
    c = mg_http_listen(&mgr, s_listening_address, cb, &mgr);
    if (c) {
        return 1;
    }
    return 0;
}

void UpdateServer() {
    mg_mgr_poll(&mgr, 1000);
}

void ShutdownServer() {
    mg_mgr_free(&mgr);
}
main.h

Code: Select all

#ifndef libpbmongoose_h__
#define libpbmongoose_h__
 
extern int StartServer();
extern void UpdateServer();
extern void ShutdownServer();
 
#endif  // libpbmongoose_h_
I compile the shared library with gcc -shared -o libmongoose.so -fPIC main.c.
Last edited by wombats on Thu Dec 24, 2020 2:45 am, edited 1 time in total.
User avatar
mk-soft
Always Here
Always Here
Posts: 5313
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Mongoose server

Post by mk-soft »

Perhaps "PrototypeC" ...
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
wombats
Enthusiast
Enthusiast
Posts: 662
Joined: Thu Dec 29, 2011 5:03 pm

Re: Mongoose server

Post by wombats »

mk-soft wrote:Perhaps "PrototypeC" ...
No joy. CallCFunction crashes, too.
infratec
Always Here
Always Here
Posts: 6810
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Mongoose server

Post by infratec »

Hm ... I think you made a mistake ...

The functions you can import are

mg_mgr_init()
mg_http_listen()
mg_mgr_poll()
mg_mgr_free()
mg_http_serve_dir()

and not

StartServer()
UpdateServer()
ShutdownServer()

You have to program these procedures.
infratec
Always Here
Always Here
Posts: 6810
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Mongoose server

Post by infratec »

More something like that, but not tested ...

Code: Select all

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf


Enumeration
  #MG_EV_ERROR      ; Error                        char *error_message
  #MG_EV_POLL       ; mg_mgr_poll iteration        unsigned long *millis
  #MG_EV_RESOLVE    ; Host name is resolved        NULL
  #MG_EV_CONNECT    ; Connection established       NULL
  #MG_EV_ACCEPT     ; Connection accepted          NULL
  #MG_EV_READ       ; Data received from socket    struct mg_str *
  #MG_EV_WRITE      ; Data written To socket       int *num_bytes_written
  #MG_EV_CLOSE      ; Connection closed            NULL
  #MG_EV_HTTP_MSG   ; HTTP request/response        struct mg_http_message *
  #MG_EV_WS_OPEN    ; Websocket handshake done     NULL
  #MG_EV_WS_MSG     ; Websocket message received   struct mg_ws_message *
  #MG_EV_WS_CTL     ; Websocket control message    struct mg_ws_message *
  #MG_EV_MQTT_CMD   ; MQTT low-level command       struct mg_mqtt_message *
  #MG_EV_MQTT_MSG   ; MQTT PUBLISH received        struct mg_mqtt_message *
  #MG_EV_MQTT_OPEN  ; MQTT CONNACK received        int *connack_status_code
  #MG_EV_SNTP_TIME  ; SNTP time received           struct timeval *
  #MG_EV_USER       ; Starting ID For user events
EndEnumeration


Prototype mg_event_handler_t(*c, ev.i, *ev_data, *fn_data)


Structure mg_addr
  port.u    ; TCP or UDP port in network byte order
  ip.l      ; IP address in network byte order
  ip6.a[16] ; IPv6 address
  is_ip6.i  ; True when address is IPv6 address
EndStructure


Structure mg_iobuf
  *buf
  len.i
EndStructure


Structure mg_connection
  *Next.mg_connection         ; Linkage in struct mg_mgr :: connections
  *mgr                        ; Our container
  peer.mg_addr                ; Remote peer address
  *fd                         ; Connected socket, or LWIP data
  id.l                        ; Auto-incrementing unique connection ID
  recv.mg_iobuf               ; Incoming data
  send.mg_iobuf               ; Outgoing data
  fn.mg_event_handler_t       ; User-specified event handler function
  *fn_data                    ; User-speficied function parameter
  pfn.mg_event_handler_t      ; Protocol-specific handler function
  *pfn_data                   ; Protocol-specific function parameter
  label.a[32]                 ; Arbitrary label
  *tls                        ; TLS specific data
  is_listening.i              ; Listening connection
  is_client.i                 ; Outbound (client) connection
  is_accepted.i               ; Accepted (server) connection
  is_resolving.i              ; Non-blocking DNS resolv is in progress
  is_connecting.i             ; Non-blocking connect is in progress
  is_tls.i                    ; TLS-enabled connection
  is_tls_hs.i                 ; TLS handshake is in progress
  is_udp.i                    ; UDP connection
  is_websocket.i              ; WebSocket connection
  is_hexdumping.i             ; Hexdump in/out traffic
  is_draining.i               ; Send remaining data, then close and free
  is_closing.i                ; Close and free the connection immediately
  is_readable.i               ; Connection is ready to read
  is_writable.i               ; Connection is ready to write
EndStructure


Structure mg_dns
  url$              ; DNS server URL
  *c.mg_connection
EndStructure


Structure mg_mgr
  *conns.mg_connection  ; List of active connections
  dns4.mg_dns           ; DNS for IPv4
  dns6.mg_dns           ; DNS for IPv6
  dnstimeout.i          ; DNS resolve timeout in milliseconds
  nextid.l
EndStructure



PrototypeC.i Prototype_mg_mgr_init(*mgr.mg_mgr)
PrototypeC.i Prototype_mg_http_listen(*mgr1.mg_mgr, s_listening_address.p-UTF8, cb.mg_event_handler_t, *mgr2.mg_mgr)
PrototypeC.i Prototype_mg_mgr_poll(*mgr.mg_mgr, ms.i)
PrototypeC.i Prototype_mg_mgr_free(*mgr.mg_mgr)
PrototypeC.i Prototype_mg_http_serve_dir(*c.mg_connection, *ev_data, s_web_root_dir.p-UTF8)


Global.i mg_mgr_init.Prototype_mg_mgr_init
Global.i mg_http_listen.Prototype_mg_http_listen
Global.i mg_mgr_poll.Prototype_mg_mgr_poll
Global.i mg_mgr_free.Prototype_mg_mgr_free
Global.i mg_http_serve_dir.Prototype_mg_http_serve_dir

Global mg_library.i

Procedure.i Load_MoonGoose()
  mg_library = OpenLibrary(#PB_Any, "libmongoose.so")
  If mg_library
    mg_mgr_init = GetFunction(mg_library, "mg_mgr_init")
    mg_http_listen = GetFunction(mg_library, "mg_http_listen")
    mg_mgr_poll = GetFunction(mg_library, "mg_mgr_poll")
    mg_mgr_free = GetFunction(mg_library, "mg_mgr_free")
    mg_http_serve_dir = GetFunction(mg_library, "mg_http_serve_dir")
  EndIf
  
  ProcedureReturn mg_library
  
EndProcedure


CompilerIf #PB_Compiler_IsMainFile
  
  Global s_web_root_dir$ = "."
  Global s_listening_address$ = "http://0.0.0.0:8000"
  
  Global mgr.mg_mgr
  Global *c.mg_connection
  
  
  
  ProcedureC CallBack(*c.mg_connection, ev.i, *ev_data, *fn_data)
    If ev = #MG_EV_HTTP_MSG
      mg_http_serve_dir(*c, *ev_data, s_web_root_dir$)
    EndIf
    ;*fn_data
  EndProcedure
  
  
  
  Procedure.i StartServer()
    
    Protected Result.i
    
    mg_mgr_init(@mgr)
    *c = mg_http_listen(@mgr, s_listening_address$, @CallBack(), @mgr)
    If *c
      Result = #True
    EndIf
    
    ProcedureReturn Result
    
  EndProcedure
  
  
  Procedure UpdateServer()
    mg_mgr_poll(@mgr, 1000)
  EndProcedure
  
  
  Procedure ShutdownServer()
    mg_mgr_free(@mgr)
  EndProcedure
  
  
  
  
  Define quit.i
  
  If Load_MoonGoose()
    
    If StartServer()
      
      OpenWindow(0, 0, 0, 320, 240, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
      
      AddWindowTimer(0, 0, 500)
      
      Repeat
        Select WaitWindowEvent()
          Case #PB_Event_Timer
            UpdateServer()
          Case #PB_Event_CloseWindow
            quit = #True
        EndSelect
      Until quit
      
      ShutdownServer()
      
    Else
      Debug "Was not able to start server"
    EndIf
    
  Else
    Debug "Was not able to load MoonGoose"
  EndIf
  
CompilerEndIf
Post Reply