protocol_example_standalone.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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. * This is a copy of dumb_increment adapted slightly to serve as the
  21. * "example-standalone-protocol", to show how to build protocol plugins
  22. * outside the library easily.
  23. */
  24. #define LWS_DLL
  25. #define LWS_INTERNAL
  26. #include "../lib/libwebsockets.h"
  27. #include <string.h>
  28. struct per_vhost_data__dumb_increment {
  29. uv_timer_t timeout_watcher;
  30. struct lws_context *context;
  31. struct lws_vhost *vhost;
  32. const struct lws_protocols *protocol;
  33. };
  34. struct per_session_data__dumb_increment {
  35. int number;
  36. };
  37. static void
  38. uv_timeout_cb_dumb_increment(uv_timer_t *w
  39. #if UV_VERSION_MAJOR == 0
  40. , int status
  41. #endif
  42. )
  43. {
  44. struct per_vhost_data__dumb_increment *vhd = lws_container_of(w,
  45. struct per_vhost_data__dumb_increment, timeout_watcher);
  46. lws_callback_on_writable_all_protocol_vhost(vhd->vhost, vhd->protocol);
  47. }
  48. static int
  49. callback_dumb_increment(struct lws *wsi, enum lws_callback_reasons reason,
  50. void *user, void *in, size_t len)
  51. {
  52. struct per_session_data__dumb_increment *pss =
  53. (struct per_session_data__dumb_increment *)user;
  54. struct per_vhost_data__dumb_increment *vhd =
  55. (struct per_vhost_data__dumb_increment *)
  56. lws_protocol_vh_priv_get(lws_get_vhost(wsi),
  57. lws_get_protocol(wsi));
  58. unsigned char buf[LWS_PRE + 512];
  59. unsigned char *p = &buf[LWS_PRE];
  60. int n, m;
  61. switch (reason) {
  62. case LWS_CALLBACK_PROTOCOL_INIT:
  63. vhd = lws_protocol_vh_priv_zalloc(lws_get_vhost(wsi),
  64. lws_get_protocol(wsi),
  65. sizeof(struct per_vhost_data__dumb_increment));
  66. vhd->context = lws_get_context(wsi);
  67. vhd->protocol = lws_get_protocol(wsi);
  68. vhd->vhost = lws_get_vhost(wsi);
  69. uv_timer_init(lws_uv_getloop(vhd->context, 0),
  70. &vhd->timeout_watcher);
  71. uv_timer_start(&vhd->timeout_watcher,
  72. uv_timeout_cb_dumb_increment, 50, 50);
  73. break;
  74. case LWS_CALLBACK_PROTOCOL_DESTROY:
  75. if (!vhd)
  76. break;
  77. uv_timer_stop(&vhd->timeout_watcher);
  78. break;
  79. case LWS_CALLBACK_ESTABLISHED:
  80. pss->number = 0;
  81. break;
  82. case LWS_CALLBACK_SERVER_WRITEABLE:
  83. n = sprintf((char *)p, "%d", pss->number++);
  84. m = lws_write(wsi, p, n, LWS_WRITE_TEXT);
  85. if (m < n) {
  86. lwsl_err("ERROR %d writing to di socket\n", n);
  87. return -1;
  88. }
  89. break;
  90. case LWS_CALLBACK_RECEIVE:
  91. if (len < 6)
  92. break;
  93. if (strcmp((const char *)in, "reset\n") == 0)
  94. pss->number = 0;
  95. if (strcmp((const char *)in, "closeme\n") == 0) {
  96. lwsl_notice("dumb_inc: closing as requested\n");
  97. lws_close_reason(wsi, LWS_CLOSE_STATUS_GOINGAWAY,
  98. (unsigned char *)"seeya", 5);
  99. return -1;
  100. }
  101. break;
  102. default:
  103. break;
  104. }
  105. return 0;
  106. }
  107. static const struct lws_protocols protocols[] = {
  108. {
  109. "example-standalone-protocol",
  110. callback_dumb_increment,
  111. sizeof(struct per_session_data__dumb_increment),
  112. 10, /* rx buf size must be >= permessage-deflate rx size */
  113. },
  114. };
  115. LWS_VISIBLE int
  116. init_protocol_example_standalone(struct lws_context *context,
  117. struct lws_plugin_capability *c)
  118. {
  119. if (c->api_magic != LWS_PLUGIN_API_MAGIC) {
  120. lwsl_err("Plugin API %d, library API %d", LWS_PLUGIN_API_MAGIC,
  121. c->api_magic);
  122. return 1;
  123. }
  124. c->protocols = protocols;
  125. c->count_protocols = ARRAY_SIZE(protocols);
  126. c->extensions = NULL;
  127. c->count_extensions = 0;
  128. return 0;
  129. }
  130. LWS_VISIBLE int
  131. destroy_protocol_example_standalone(struct lws_context *context)
  132. {
  133. return 0;
  134. }