Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"en-US,en;q\u003d0.5", "gen_ut":1571203001, "reponame":"libwebsockets", "desc":"libwebsockets lightweight C networking library", "owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://libwebsockets.org/repo/libwebsockets", "f":3, "items": [ {"schema":"libjg2-1", "cid":"a4b57faf14e681d2c6deee62529d416b", "oid":{ "oid": "1cae39bb695b7201d43e8cc25eda98e625ceae2f", "alias": [ "refs/heads/master"]},"blobname": "minimal-examples/ws-client/minimal-ws-client-echo/protocol_lws_minimal_client_echo.c", "blob": "/*\n * ws protocol handler plugin for \u0022lws-minimal-client-echo\u0022\n *\n * Written in 2010-2019 by Andy Green \u003candy@warmcat.com\u003e\n *\n * This file is made available under the Creative Commons CC0 1.0\n * Universal Public Domain Dedication.\n *\n * The protocol shows how to send and receive bulk messages over a ws connection\n * that optionally may have the permessage-deflate extension negotiated on it.\n */\n\n#if !defined (LWS_PLUGIN_STATIC)\n#define LWS_DLL\n#define LWS_INTERNAL\n#include \u003clibwebsockets.h\u003e\n#endif\n\n#include \u003cstring.h\u003e\n\n#define RING_DEPTH 1024\n\n/* one of these created for each message */\n\nstruct msg {\n\tvoid *payload; /* is malloc'd */\n\tsize_t len;\n\tchar binary;\n\tchar first;\n\tchar final;\n};\n\nstruct per_session_data__minimal_client_echo {\n\tstruct lws_ring *ring;\n\tuint32_t tail;\n\tchar flow_controlled;\n\tuint8_t completed:1;\n\tuint8_t write_consume_pending:1;\n};\n\nstruct vhd_minimal_client_echo {\n\tstruct lws_context *context;\n\tstruct lws_vhost *vhost;\n\tstruct lws *client_wsi;\n\n\tint *interrupted;\n\tint *options;\n\tconst char **url;\n\tconst char **ads;\n\tconst char **iface;\n\tint *port;\n};\n\nstatic int\nconnect_client(struct vhd_minimal_client_echo *vhd)\n{\n\tstruct lws_client_connect_info i;\n\tchar host[128];\n\n\tlws_snprintf(host, sizeof(host), \u0022%s:%u\u0022, *vhd-\u003eads, *vhd-\u003eport);\n\n\tmemset(\u0026i, 0, sizeof(i));\n\n\ti.context \u003d vhd-\u003econtext;\n\ti.port \u003d *vhd-\u003eport;\n\ti.address \u003d *vhd-\u003eads;\n\ti.path \u003d *vhd-\u003eurl;\n\ti.host \u003d host;\n\ti.origin \u003d host;\n\ti.ssl_connection \u003d 0;\n\tif ((*vhd-\u003eoptions) \u0026 2)\n\t\ti.ssl_connection |\u003d LCCSCF_USE_SSL;\n\ti.vhost \u003d vhd-\u003evhost;\n\ti.iface \u003d *vhd-\u003eiface;\n\t//i.protocol \u003d ;\n\ti.pwsi \u003d \u0026vhd-\u003eclient_wsi;\n\n\tlwsl_user(\u0022connecting to %s:%d/%s\u005cn\u0022, i.address, i.port, i.path);\n\n\treturn !lws_client_connect_via_info(\u0026i);\n}\n\nstatic void\n__minimal_destroy_message(void *_msg)\n{\n\tstruct msg *msg \u003d _msg;\n\n\tfree(msg-\u003epayload);\n\tmsg-\u003epayload \u003d NULL;\n\tmsg-\u003elen \u003d 0;\n}\n\nstatic void\nschedule_callback(struct lws *wsi, int reason, int secs)\n{\n\tlws_timed_callback_vh_protocol(lws_get_vhost(wsi),\n\t\tlws_get_protocol(wsi), reason, secs);\n}\n\nstatic int\ncallback_minimal_client_echo(struct lws *wsi, enum lws_callback_reasons reason,\n\t\t\t void *user, void *in, size_t len)\n{\n\tstruct per_session_data__minimal_client_echo *pss \u003d\n\t\t\t(struct per_session_data__minimal_client_echo *)user;\n\tstruct vhd_minimal_client_echo *vhd \u003d (struct vhd_minimal_client_echo *)\n\t\t\tlws_protocol_vh_priv_get(lws_get_vhost(wsi),\n\t\t\t\tlws_get_protocol(wsi));\n\tconst struct msg *pmsg;\n\tstruct msg amsg;\n\tint n, m, flags;\n\n\tswitch (reason) {\n\n\tcase LWS_CALLBACK_PROTOCOL_INIT:\n\t\tvhd \u003d lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),\n\t\t\t\tlws_get_protocol(wsi),\n\t\t\t\tsizeof(struct vhd_minimal_client_echo));\n\t\tif (!vhd)\n\t\t\treturn -1;\n\n\t\tvhd-\u003econtext \u003d lws_get_context(wsi);\n\t\tvhd-\u003evhost \u003d lws_get_vhost(wsi);\n\n\t\t/* get the pointer to \u0022interrupted\u0022 we were passed in pvo */\n\t\tvhd-\u003einterrupted \u003d (int *)lws_pvo_search(\n\t\t\t(const struct lws_protocol_vhost_options *)in,\n\t\t\t\u0022interrupted\u0022)-\u003evalue;\n\t\tvhd-\u003eport \u003d (int *)lws_pvo_search(\n\t\t\t(const struct lws_protocol_vhost_options *)in,\n\t\t\t\u0022port\u0022)-\u003evalue;\n\t\tvhd-\u003eoptions \u003d (int *)lws_pvo_search(\n\t\t\t(const struct lws_protocol_vhost_options *)in,\n\t\t\t\u0022options\u0022)-\u003evalue;\n\t\tvhd-\u003eads \u003d (const char **)lws_pvo_search(\n\t\t\t(const struct lws_protocol_vhost_options *)in,\n\t\t\t\u0022ads\u0022)-\u003evalue;\n\t\tvhd-\u003eurl \u003d (const char **)lws_pvo_search(\n\t\t\t(const struct lws_protocol_vhost_options *)in,\n\t\t\t\u0022url\u0022)-\u003evalue;\n\t\tvhd-\u003eiface \u003d (const char **)lws_pvo_search(\n\t\t\t(const struct lws_protocol_vhost_options *)in,\n\t\t\t\u0022iface\u0022)-\u003evalue;\n\n\t\tif (connect_client(vhd))\n\t\t\tschedule_callback(wsi, LWS_CALLBACK_USER, 1);\n\t\tbreak;\n\n\tcase LWS_CALLBACK_CLIENT_ESTABLISHED:\n\t\tlwsl_user(\u0022LWS_CALLBACK_CLIENT_ESTABLISHED\u005cn\u0022);\n\t\tpss-\u003ering \u003d lws_ring_create(sizeof(struct msg), RING_DEPTH,\n\t\t\t\t\t __minimal_destroy_message);\n\t\tif (!pss-\u003ering)\n\t\t\treturn 1;\n\t\tpss-\u003etail \u003d 0;\n\t\tbreak;\n\n\tcase LWS_CALLBACK_CLIENT_WRITEABLE:\n\n\t\tlwsl_user(\u0022LWS_CALLBACK_CLIENT_WRITEABLE\u005cn\u0022);\n\n\t\tif (pss-\u003ewrite_consume_pending) {\n\t\t\t/* perform the deferred fifo consume */\n\t\t\tlws_ring_consume_single_tail(pss-\u003ering, \u0026pss-\u003etail, 1);\n\t\t\tpss-\u003ewrite_consume_pending \u003d 0;\n\t\t}\n\t\tpmsg \u003d lws_ring_get_element(pss-\u003ering, \u0026pss-\u003etail);\n\t\tif (!pmsg) {\n\t\t\tlwsl_user(\u0022 (nothing in ring)\u005cn\u0022);\n\t\t\tbreak;\n\t\t}\n\n\t\tflags \u003d lws_write_ws_flags(\n\t\t\t pmsg-\u003ebinary ? LWS_WRITE_BINARY : LWS_WRITE_TEXT,\n\t\t\t pmsg-\u003efirst, pmsg-\u003efinal);\n\n\t\t/* notice we allowed for LWS_PRE in the payload already */\n\t\tm \u003d lws_write(wsi, ((unsigned char *)pmsg-\u003epayload) +\n\t\t\t LWS_PRE, pmsg-\u003elen, flags);\n\t\tif (m \u003c (int)pmsg-\u003elen) {\n\t\t\tlwsl_err(\u0022ERROR %d writing to ws socket\u005cn\u0022, m);\n\t\t\treturn -1;\n\t\t}\n\n\t\tlwsl_user(\u0022 wrote %d: flags: 0x%x first: %d final %d\u005cn\u0022,\n\t\t\t\tm, flags, pmsg-\u003efirst, pmsg-\u003efinal);\n\n\t\tif ((*vhd-\u003eoptions \u0026 1) \u0026\u0026 pmsg \u0026\u0026 pmsg-\u003efinal)\n\t\t\tpss-\u003ecompleted \u003d 1;\n\n\t\t/*\n\t\t * Workaround deferred deflate in pmd extension by only\n\t\t * consuming the fifo entry when we are certain it has been\n\t\t * fully deflated at the next WRITABLE callback. You only need\n\t\t * this if you're using pmd.\n\t\t */\n\t\tpss-\u003ewrite_consume_pending \u003d 1;\n\t\tlws_callback_on_writable(wsi);\n\n\t\tif (pss-\u003eflow_controlled \u0026\u0026\n\t\t (int)lws_ring_get_count_free_elements(pss-\u003ering) \u003e RING_DEPTH - 5) {\n\t\t\tlws_rx_flow_control(wsi, 1);\n\t\t\tpss-\u003eflow_controlled \u003d 0;\n\t\t}\n\n\t\tbreak;\n\n\tcase LWS_CALLBACK_CLIENT_RECEIVE:\n\n\t\tlwsl_user(\u0022LWS_CALLBACK_CLIENT_RECEIVE: %4d (rpp %5d, first %d, last %d, bin %d)\u005cn\u0022,\n\t\t\t(int)len, (int)lws_remaining_packet_payload(wsi),\n\t\t\tlws_is_first_fragment(wsi),\n\t\t\tlws_is_final_fragment(wsi),\n\t\t\tlws_frame_is_binary(wsi));\n\n\t\t// lwsl_hexdump_notice(in, len);\n\n\t\tamsg.first \u003d lws_is_first_fragment(wsi);\n\t\tamsg.final \u003d lws_is_final_fragment(wsi);\n\t\tamsg.binary \u003d lws_frame_is_binary(wsi);\n\t\tn \u003d (int)lws_ring_get_count_free_elements(pss-\u003ering);\n\t\tif (!n) {\n\t\t\tlwsl_user(\u0022dropping!\u005cn\u0022);\n\t\t\tbreak;\n\t\t}\n\n\t\tamsg.len \u003d len;\n\t\t/* notice we over-allocate by LWS_PRE */\n\t\tamsg.payload \u003d malloc(LWS_PRE + len);\n\t\tif (!amsg.payload) {\n\t\t\tlwsl_user(\u0022OOM: dropping\u005cn\u0022);\n\t\t\tbreak;\n\t\t}\n\n\t\tmemcpy((char *)amsg.payload + LWS_PRE, in, len);\n\t\tif (!lws_ring_insert(pss-\u003ering, \u0026amsg, 1)) {\n\t\t\t__minimal_destroy_message(\u0026amsg);\n\t\t\tlwsl_user(\u0022dropping!\u005cn\u0022);\n\t\t\tbreak;\n\t\t}\n\t\tlws_callback_on_writable(wsi);\n\n\t\tif (!pss-\u003eflow_controlled \u0026\u0026 n \u003c 3) {\n\t\t\tpss-\u003eflow_controlled \u003d 1;\n\t\t\tlws_rx_flow_control(wsi, 0);\n\t\t}\n\t\tbreak;\n\n\tcase LWS_CALLBACK_CLIENT_CONNECTION_ERROR:\n\t\tlwsl_err(\u0022CLIENT_CONNECTION_ERROR: %s\u005cn\u0022,\n\t\t\t in ? (char *)in : \u0022(null)\u0022);\n\t\tvhd-\u003eclient_wsi \u003d NULL;\n\t\t//schedule_callback(wsi, LWS_CALLBACK_USER, 1);\n\t\t//if (*vhd-\u003eoptions \u0026 1) {\n\t\t\tif (!*vhd-\u003einterrupted)\n\t\t\t\t*vhd-\u003einterrupted \u003d 3;\n\t\t\tlws_cancel_service(lws_get_context(wsi));\n\t\t//}\n\t\tbreak;\n\n\tcase LWS_CALLBACK_CLIENT_CLOSED:\n\t\tlwsl_user(\u0022LWS_CALLBACK_CLIENT_CLOSED\u005cn\u0022);\n\t\tlws_ring_destroy(pss-\u003ering);\n\t\tvhd-\u003eclient_wsi \u003d NULL;\n\t\t// schedule_callback(wsi, LWS_CALLBACK_USER, 1);\n\t\t//if (*vhd-\u003eoptions \u0026 1) {\n\t\t\tif (!*vhd-\u003einterrupted)\n\t\t\t\t*vhd-\u003einterrupted \u003d 1 + pss-\u003ecompleted;\n\t\t\tlws_cancel_service(lws_get_context(wsi));\n\t//\t}\n\t\tbreak;\n\n\t/* rate-limited client connect retries */\n\n\tcase LWS_CALLBACK_USER:\n\t\tlwsl_notice(\u0022%s: LWS_CALLBACK_USER\u005cn\u0022, __func__);\n\t\tif (connect_client(vhd))\n\t\t\tschedule_callback(wsi, LWS_CALLBACK_USER, 1);\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\n#define LWS_PLUGIN_PROTOCOL_MINIMAL_CLIENT_ECHO \u005c\n\t{ \u005c\n\t\t\u0022lws-minimal-client-echo\u0022, \u005c\n\t\tcallback_minimal_client_echo, \u005c\n\t\tsizeof(struct per_session_data__minimal_client_echo), \u005c\n\t\t1024, \u005c\n\t\t0, NULL, 0 \u005c\n\t}\n\n#if !defined (LWS_PLUGIN_STATIC)\n\n/* boilerplate needed if we are built as a dynamic plugin */\n\nstatic const struct lws_protocols protocols[] \u003d {\n\tLWS_PLUGIN_PROTOCOL_MINIMAL_CLIENT_ECHO\n};\n\nLWS_EXTERN LWS_VISIBLE int\ninit_protocol_minimal_client_echo(struct lws_context *context,\n\t\t\t struct lws_plugin_capability *c)\n{\n\tif (c-\u003eapi_magic !\u003d LWS_PLUGIN_API_MAGIC) {\n\t\tlwsl_err(\u0022Plugin API %d, library API %d\u0022, LWS_PLUGIN_API_MAGIC,\n\t\t\t c-\u003eapi_magic);\n\t\treturn 1;\n\t}\n\n\tc-\u003eprotocols \u003d protocols;\n\tc-\u003ecount_protocols \u003d LWS_ARRAY_SIZE(protocols);\n\tc-\u003eextensions \u003d NULL;\n\tc-\u003ecount_extensions \u003d 0;\n\n\treturn 0;\n}\n\nLWS_EXTERN LWS_VISIBLE int\ndestroy_protocol_minimal_client_echo(struct lws_context *context)\n{\n\treturn 0;\n}\n#endif\n","s":{"c":1571157788,"u": 454}} ],"g": 614,"chitpc": 0,"ehitpc": 0, "indexed":0 }