[Libwebsockets] How to pass global user defined structures to each callbacks

Andy Green andy at warmcat.com
Sun Jun 12 19:02:18 CEST 2016



On June 13, 2016 12:20:45 AM GMT+08:00, Meir Yanovich <meiry242 at gmail.com> wrote:
>Hello
>im not sure if this related to lws but i just can't find way to pass

It's only about lws so you stand a chance somebody knows what you're talking about.

>global
>structure which holds its values between the callbacks .

When you create the context, you can set info->user, it's ignored by lws but you can set it to point to a struct with your 'important things'.

>From the callback, you can use this

LWS_VISIBLE LWS_EXTERN void *
lws_context_user(struct lws_context *context);

to get the pointer and cast it.

>the simple story is that i have simple hashtable in C
>https://github.com/cgjones/android-system-core/blob/master/libcutils/hashmap.c
>
>i try to explain in the example :
>i have the main :
>
>
>//HERE I DEFINE IT AS GLOBAL
>Hashmap *users_map;
>
>static struct lws_protocols protocols[] = {
>{
>"wsapi",
>callback_wsapi,
>sizeof(struct per_session_data__apigataway),
>128,
>} ,
>{ NULL, NULL, 0, 0 } /* terminator */
>};
>
>int main(int argc, char **argv)
>{
>struct lws_context_creation_info info;
>
>//HERE i init the hash map
>users_map = hashmapCreate(10, str_hash_fn, str_eq);
>memset(&info, 0, sizeof info);
>info.port = server_port;
>info.protocols = protocols;
>...
>info.options = opts | LWS_SERVER_OPTION_LIBUV;
>context = lws_create_context(&info);
>if (lws_uv_initloop(context, NULL, 0)) {
>lwsl_err("lws_uv_initloop failed\n");
>goto bail;
>}
>uv_timer_init(lws_uv_getloop(context, 0), &timeout_watcher);
>uv_timer_start(&timeout_watcher, main_loop_count_callback, 1000, 1000);
>lws_libuv_run(context, 0);
>return 0;
>}
>
>
>
>and this is the callback_wsapi C file i removed allot of code just to
>show
>the important stuff
>
>//HERE I SET IT AS EXTERN SO IT WILL BE VISIBLE TO ALL
>extern Hashmap *users_map;
>
>int
>callback_iogame(struct lws *wsi, enum lws_callback_reasons reason,
>void *user, void *in, size_t len)
>{
>unsigned char out[LWS_PRE + 512];
>struct per_session_data__apigataway *pss =
>(struct per_session_data__apigataway *)user;
>switch (reason) {
>case LWS_CALLBACK_ESTABLISHED:
>break;
>case LWS_CALLBACK_SERVER_WRITEABLE:
>{
>//HERE IT LOSSING SCOPE AND THE HASHMAP NOT INITIALIZED
>int bfor2 = hashmapSize(users_map);
>break;
>}
>case LWS_CALLBACK_RECEIVE:
>{
>char* client_req_str;
>client_req_str = (char*)in;
>
>if (strncmp((const char *)client_req_str, "player\n",6) == 0)
>{
>//ON THE FIRST REQUEST FROM THE CLINET IT WORKS
>int bfor  = hashmapSize(users_map);
>hashmapPut(users_map, pss->id, pss);
>int after = hashmapSize(users_map);
>  }
>//Only invoke callback back to client when baby client is ready to eat
>lws_callback_on_writable(wsi);
>break;
>}
>case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION:
>
>break;
>case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
>break;
>default:
>break;
>}
>
>
>
>
>
>So i can get the hashmap only in the first request when it gets to :
>LWS_CALLBACK_RECEIVE
>then it just losing scope .
>
>
>Questions :
>1. How can i make this hashmap global to the callbacks ? it supposed to
>hold the server total users  .

As explained, use info->user is the best way.

But I'm not sure that's your problem since making it available as a global is doing the same thing if no plugins involved.

The global is not 'losing scope', it's a global.  Something else is happening.

Since it's not related to 'scope', it's doubtful is suddenly became 'not initialized'.

Is it possible you simply got a writable callback before you received something and added to the hashtable?

>2. is there is way to set user defined parameters and pass them between
>callbacks ?

"parameters" means "callback reasons"?  Yes you can make private reasons starting from LWS_CALLBACK_USER, that won't clash with any lws ones.

If not please explain what you mean.

>Thanks
>
>
>As side note
>i saw something in ibwebsockets.h line 1561 written there :
>/* Add new things just above here ---^
>is this is the place i can add new members which can be passed ?

You shouldn't have to modify libwebsockets.h unless you're adding something to the library.  And that shouldn't be necessary for the normal case.

-Andy

>
>------------------------------------------------------------------------
>
>_______________________________________________
>Libwebsockets mailing list
>Libwebsockets at ml.libwebsockets.org
>http://libwebsockets.org/mailman/listinfo/libwebsockets




More information about the Libwebsockets mailing list