websocket_chat.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * Copyright (c) 2014 Cesanta Software Limited
  3. * All rights reserved
  4. */
  5. #define LOG_TAG "mg.demo.wc"
  6. #include <elog.h>
  7. #include <finsh.h>
  8. #include "mongoose.h"
  9. static const char *s_http_port = "8001";
  10. static int is_websocket(const struct mg_connection *nc) {
  11. return nc->flags & MG_F_IS_WEBSOCKET;
  12. }
  13. static void broadcast(struct mg_connection *nc, const struct mg_str msg) {
  14. struct mg_connection *c;
  15. char buf[500];
  16. char addr[32];
  17. mg_sock_addr_to_str(&nc->sa, addr, sizeof(addr), MG_SOCK_STRINGIFY_IP | MG_SOCK_STRINGIFY_PORT);
  18. snprintf(buf, sizeof(buf), "%s %.*s", addr, (int) msg.len, msg.p);
  19. rt_kprintf("%s\n", buf); /* Local echo. */
  20. for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) {
  21. if (c == nc || (c->flags & MG_F_LISTENING) || !is_websocket(nc))
  22. continue; /* Don't send to the sender or listen connection. */
  23. mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, buf, strlen(buf));
  24. }
  25. }
  26. static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
  27. switch (ev) {
  28. case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
  29. /* New websocket connection. Tell everybody. */
  30. broadcast(nc, mg_mk_str("++ joined"));
  31. break;
  32. }
  33. case MG_EV_WEBSOCKET_FRAME: {
  34. struct websocket_message *wm = (struct websocket_message *) ev_data;
  35. /* New websocket message. Tell everybody. */
  36. struct mg_str d = { (char *) wm->data, wm->size };
  37. broadcast(nc, d);
  38. break;
  39. }
  40. case MG_EV_CLOSE: {
  41. /* Disconnect. Tell everybody. */
  42. if (is_websocket(nc)) {
  43. broadcast(nc, mg_mk_str("-- left"));
  44. }
  45. break;
  46. }
  47. }
  48. }
  49. static void websocket_entry(void *param) {
  50. struct mg_mgr mgr;
  51. struct mg_connection *nc;
  52. mg_mgr_init(&mgr, NULL);
  53. nc = mg_bind(&mgr, s_http_port, ev_handler);
  54. mg_set_protocol_http_websocket(nc);
  55. rt_kprintf("Started on port %s\n", s_http_port);
  56. while (true) {
  57. mg_mgr_poll(&mgr, 200);
  58. rt_thread_delay(rt_tick_from_millisecond(200));
  59. }
  60. // mg_mgr_free(&mgr);
  61. }
  62. static void mg_demo_wc(uint8_t argc, char **argv) {
  63. /* ³õʼ»¯Íê³É */
  64. static bool init_ok = false;
  65. if (init_ok) {
  66. rt_kprintf("already start Mongoose Demo: websocket chat\n");
  67. return;
  68. }
  69. rt_thread_t thread = rt_thread_create("mg_demo_wc", websocket_entry, NULL, 4096, 19, 25);
  70. if (thread) {
  71. rt_thread_startup(thread);
  72. /* ³õʼ»¯Íê³É */
  73. init_ok = true;
  74. }
  75. }
  76. MSH_CMD_EXPORT(mg_demo_wc, Mongoose Demo websocket chat);