Statistics
| Branch: | Tag: | Revision:

mongoose / examples / publish_subscribe / publish_subscribe.c @ eaef5bd1

History | View | Annotate | Download (3.46 KB)

1
// Copyright (c) 2014 Cesanta Software Limited
2
// All rights reserved
3
//
4
// This software is dual-licensed: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License version 2 as
6
// published by the Free Software Foundation. For the terms of this
7
// license, see <http://www.gnu.org/licenses/>.
8
//
9
// You are free to use this software under the terms of the GNU General
10
// Public License, but WITHOUT ANY WARRANTY; without even the implied
11
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
// See the GNU General Public License for more details.
13
//
14
// Alternatively, you can license this software under a commercial
15
// license, as set out in <https://www.cesanta.com/license>.
16
//
17
// $Date: 2014-09-28 05:04:41 UTC $
18

    
19
#include "mongoose.h"
20

    
21
static void *stdin_thread(void *param) {
22
  int ch, sock = *(int *) param;
23
  // Forward all types characters to the socketpair
24
  while ((ch = getchar()) != EOF) {
25
    unsigned char c = (unsigned char) ch;
26
    send(sock, (const char *) &c, 1, 0);
27
  }
28
  return NULL;
29
}
30

    
31
static void server_handler(struct mg_connection *nc, int ev, void *p) {
32
  (void) p;
33
  if (ev == MG_EV_RECV) {
34
    // Push received message to all ncections
35
    struct mbuf *io = &nc->recv_mbuf;
36
    struct mg_connection *c;
37

    
38
    for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) {
39
      mg_send(c, io->buf, io->len);
40
    }
41
    mbuf_remove(io, io->len);
42
  }
43
}
44

    
45
static void client_handler(struct mg_connection *conn, int ev, void *p) {
46
  struct mbuf *io = &conn->recv_mbuf;
47
  (void) p;
48

    
49
  if (ev == MG_EV_CONNECT) {
50
    if (conn->flags & MG_F_CLOSE_IMMEDIATELY) {
51
      printf("%s\n", "Error connecting to server!");
52
      exit(EXIT_FAILURE);
53
    }
54
    printf("%s\n", "Connected to server. Type a message and press enter.");
55
  } else if (ev == MG_EV_RECV) {
56
    if (conn->flags & MG_F_USER_1) {
57
      // Received data from the stdin, forward it to the server
58
      struct mg_connection *c = (struct mg_connection *) conn->user_data;
59
      mg_send(c, io->buf, io->len);
60
      mbuf_remove(io, io->len);
61
    } else {
62
      // Received data from server connection, print it
63
      fwrite(io->buf, io->len, 1, stdout);
64
      mbuf_remove(io, io->len);
65
    }
66
  } else if (ev == MG_EV_CLOSE) {
67
    // Connection has closed, most probably cause server has stopped
68
    exit(EXIT_SUCCESS);
69
  }
70
}
71

    
72
int main(int argc, char *argv[]) {
73
  struct mg_mgr mgr;
74

    
75
  if (argc != 3) {
76
    fprintf(stderr, "Usage: %s <port> <client|server>\n", argv[0]);
77
    exit(EXIT_FAILURE);
78
  } else if (strcmp(argv[2], "client") == 0) {
79
    sock_t fds[2];
80
    struct mg_connection *ioconn, *server_conn;
81

    
82
    mg_mgr_init(&mgr, NULL);
83

    
84
    // Connect to the pubsub server
85
    server_conn = mg_connect(&mgr, argv[1], client_handler);
86
    if (server_conn == NULL) {
87
      fprintf(stderr, "Cannot connect to port %s\n", argv[1]);
88
      exit(EXIT_FAILURE);
89
    }
90

    
91
    // Create a socketpair and give one end to the thread that reads stdin
92
    mg_socketpair(fds, SOCK_STREAM);
93
    mg_start_thread(stdin_thread, &fds[1]);
94

    
95
    // The other end of a pair goes inside the server
96
    ioconn = mg_add_sock(&mgr, fds[0], client_handler);
97
    ioconn->flags |= MG_F_USER_1;  // Mark this so we know this is a stdin
98
    ioconn->user_data = server_conn;
99

    
100
  } else {
101
    // Server code path
102
    mg_mgr_init(&mgr, NULL);
103
    mg_bind(&mgr, argv[1], server_handler);
104
    printf("Starting pubsub server on port %s\n", argv[1]);
105
  }
106

    
107
  for (;;) {
108
    mg_mgr_poll(&mgr, 1000);
109
  }
110
  mg_mgr_free(&mgr);
111

    
112
  return EXIT_SUCCESS;
113
}