protocol_dumb_increment.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * ws protocol handler plugin for "dumb increment"
  3. *
  4. * Copyright (C) 2010-2016 Andy Green <andy@warmcat.com>
  5. *
  6. * This file is made available under the Creative Commons CC0 1.0
  7. * Universal Public Domain Dedication.
  8. *
  9. * The person who associated a work with this deed has dedicated
  10. * the work to the public domain by waiving all of his or her rights
  11. * to the work worldwide under copyright law, including all related
  12. * and neighboring rights, to the extent allowed by law. You can copy,
  13. * modify, distribute and perform the work, even for commercial purposes,
  14. * all without asking permission.
  15. *
  16. * These test plugins are intended to be adapted for use in your code, which
  17. * may be proprietary. So unlike the library itself, they are licensed
  18. * Public Domain.
  19. */
  20. #if !defined (LWS_PLUGIN_STATIC)
  21. #define LWS_DLL
  22. #define LWS_INTERNAL
  23. #include "../lib/libwebsockets.h"
  24. #endif
  25. #include <string.h>
  26. #if defined(LWS_WITH_ESP8266)
  27. #define DUMB_PERIOD 50
  28. #else
  29. #define DUMB_PERIOD 50
  30. #endif
  31. struct per_vhost_data__dumb_increment {
  32. uv_timer_t timeout_watcher;
  33. struct lws_context *context;
  34. struct lws_vhost *vhost;
  35. const struct lws_protocols *protocol;
  36. };
  37. struct per_session_data__dumb_increment {
  38. int number;
  39. };
  40. static void
  41. uv_timeout_cb_dumb_increment(uv_timer_t *w
  42. #if UV_VERSION_MAJOR == 0
  43. , int status
  44. #endif
  45. )
  46. {
  47. struct per_vhost_data__dumb_increment *vhd = lws_container_of(w,
  48. struct per_vhost_data__dumb_increment, timeout_watcher);
  49. lws_callback_on_writable_all_protocol_vhost(vhd->vhost, vhd->protocol);
  50. }
  51. static int
  52. callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
  53. void *user, void *in, size_t len)
  54. {
  55. struct per_session_data__dumb_increment *pss =
  56. (struct per_session_data__dumb_increment *)user;
  57. struct per_vhost_data__dumb_increment *vhd =
  58. (struct per_vhost_data__dumb_increment *)
  59. lws_protocol_vh_priv_get(lws_get_vhost(wsi),
  60. lws_get_protocol(wsi));
  61. unsigned char buf[LWS_PRE + 20];
  62. unsigned char *p = &buf[LWS_PRE];
  63. int n, m;
  64. switch (reason) {
  65. case LWS_CALLBACK_PROTOCOL_INIT:
  66. vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
  67. lws_get_protocol(wsi),
  68. sizeof(struct per_vhost_data__dumb_increment));
  69. vhd->context = lws_get_context(wsi);
  70. vhd->protocol = lws_get_protocol(wsi);
  71. vhd->vhost = lws_get_vhost(wsi);
  72. uv_timer_init(lws_uv_getloop(vhd->context, 0),
  73. &vhd->timeout_watcher);
  74. uv_timer_start(&vhd->timeout_watcher,
  75. uv_timeout_cb_dumb_increment, DUMB_PERIOD, DUMB_PERIOD);
  76. break;
  77. case LWS_CALLBACK_PROTOCOL_DESTROY:
  78. if (!vhd)
  79. break;
  80. // lwsl_notice("di: LWS_CALLBACK_PROTOCOL_DESTROY: v=%p, ctx=%p\n", vhd, vhd->context);
  81. uv_timer_stop(&vhd->timeout_watcher);
  82. uv_close((uv_handle_t *)&vhd->timeout_watcher, NULL);
  83. break;
  84. case LWS_CALLBACK_ESTABLISHED:
  85. pss->number = 0;
  86. break;
  87. case LWS_CALLBACK_SERVER_WRITEABLE:
  88. n = lws_snprintf((char *)p, sizeof(buf) - LWS_PRE, "%d", pss->number++);
  89. m = lws_write(wsi, p, n, LWS_WRITE_TEXT);
  90. if (m < n) {
  91. lwsl_err("ERROR %d writing to di socket\n", n);
  92. return -1;
  93. }
  94. break;
  95. case LWS_CALLBACK_RECEIVE:
  96. if (len < 6)
  97. break;
  98. if (strcmp((const char *)in, "reset\n") == 0)
  99. pss->number = 0;
  100. if (strcmp((const char *)in, "closeme\n") == 0) {
  101. lwsl_notice("dumb_inc: closing as requested\n");
  102. lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY,
  103. (unsigned char *)"seeya", 5);
  104. return -1;
  105. }
  106. break;
  107. default:
  108. break;
  109. }
  110. return 0;
  111. }
  112. #define LWS_PLUGIN_PROTOCOL_DUMB_INCREMENT \
  113. { \
  114. "dumb-increment-protocol", \
  115. callback_dumb_increment, \
  116. sizeof(struct per_session_data__dumb_increment), \
  117. 10, /* rx buf size must be >= permessage-deflate rx size */ \
  118. }
  119. #if !defined (LWS_PLUGIN_STATIC)
  120. static const struct lws_protocols protocols[] = {
  121. LWS_PLUGIN_PROTOCOL_DUMB_INCREMENT
  122. };
  123. LWS_EXTERN LWS_VISIBLE int
  124. init_protocol_dumb_increment(struct lws_context *context,
  125. struct lws_plugin_capability *c)
  126. {
  127. if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
  128. lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
  129. c->api_magic);
  130. return 1;
  131. }
  132. c->protocols = protocols;
  133. c->count_protocols = ARRAY_SIZE(protocols);
  134. c->extensions = NULL;
  135. c->count_extensions = 0;
  136. return 0;
  137. }
  138. LWS_EXTERN LWS_VISIBLE int
  139. destroy_protocol_dumb_increment(struct lws_context *context)
  140. {
  141. return 0;
  142. }
  143. #endif