Merge dev branch code named Fossa as next stable Mongoose

This commit is contained in:
Marko Mikulicic committed 2015-09-08 14:34:30 +02:00
1 parent 28eb251ccd
commit 8927c9d22b
126 files changed
+162049 -8502

No files matched your search

+14 -27
View File
@@ -6,7 +6,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #cde; margin: 0;
background-color: #789; margin: 0;
padding: 0; font: 14px Helvetica, Arial, sans-serif;
}
div.content {
@@ -39,24 +39,22 @@
ws.onclose = function(ev) { console.log(ev); };
ws.onmessage = function(ev) {
console.log(ev);
var m = (ev.data || '').match(/^(\S+) (.+)/);
if (m[1] == 'id') {
document.getElementById('my_id').innerText = m[2];
} else if (m[1] == 'msg') {
var div = document.createElement('div');
div.innerHTML = m[2];
document.getElementById('messages').appendChild(div);
}
var div = document.createElement('div');
div.innerHTML = ev.data;
document.getElementById('messages').appendChild(div);
};
window.onload = function() {
document.getElementById('send_button').onclick = function(ev) {
var msg = document.getElementById('send_input').value;
ws.send('msg ' + msg);
document.getElementById('send_input').value = '';
ws.send(msg);
};
document.getElementById('room_sel').onchange = function(ev) {
var roomName = this.value || '?';
ws.send('join ' + roomName);
document.getElementById('send_input').onkeypress = function(ev) {
if (ev.keyCode == 13 || ev.which == 13) {
document.getElementById('send_button').click();
}
};
};
</script>
@@ -66,24 +64,13 @@
<h1>Websocket PubSub Demonstration</h1>
<p>
This page demonstrates how Mongoose web server could be used to implement
This page demonstrates how Mongoose could be used to implement
<a href="http://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern">
publish–subscribe pattern</a>. Open this page in several browser
windows. Each window initiates persistent
<a href="http://en.wikipedia.org/wiki/WebSocket">WebSocket</a>
connection with Mongoose, making each browser window a websocket client.
Join a room, send messages, and see messages sent by other clients.
</p>
<p>
My ID: <b><span id="my_id"></b></span>
</p>
<p>
Join room: <select id="room_sel">
<option value="">-- select room -- </option>
<option>A</option>
<option>B</option>
</select>
connection with the server, making each browser window a websocket client.
Send messages, and see messages sent by other clients.
</p>
<div id="messages">
+52 -55
View File
@@ -1,83 +1,80 @@
// Copyright (c) 2013-2014 Cesanta Software Limited
// $Date: 2014-09-09 17:07:55 UTC $
/*
* Copyright (c) 2014 Cesanta Software Limited
* All rights reserved
*/
#include <string.h>
#include <time.h>
#include <signal.h>
#include <stdlib.h>
#include "mongoose.h"
static int s_signal_received = 0;
static struct mg_server *s_server = NULL;
// Data associated with each websocket connection
struct conn_data {
int room;
};
static sig_atomic_t s_signal_received = 0;
static const char *s_http_port = "8000";
static struct mg_serve_http_opts s_http_server_opts;
static void signal_handler(int sig_num) {
signal(sig_num, signal_handler); // Reinstantiate signal handler
s_signal_received = sig_num;
}
static void handle_websocket_message(struct mg_connection *conn) {
struct conn_data *d = (struct conn_data *) conn->connection_param;
struct mg_connection *c;
static int is_websocket(const struct mg_connection *nc) {
return nc->flags & NSF_IS_WEBSOCKET;
}
printf("[%.*s]\n", (int) conn->content_len, conn->content);
if (conn->content_len > 5 && !memcmp(conn->content, "join ", 5)) {
// Client joined new room
d->room = conn->content[5];
} else if (conn->content_len > 4 && !memcmp(conn->content, "msg ", 4) &&
d->room != 0 && d->room != '?') {
// Client has sent a message. Push this message to all clients
// that are subscribed to the same room as client
for (c = mg_next(s_server, NULL); c != NULL; c = mg_next(s_server, c)) {
struct conn_data *d2 = (struct conn_data *) c->connection_param;
if (!c->is_websocket || d2->room != d->room) continue;
mg_websocket_printf(c, WEBSOCKET_OPCODE_TEXT, "msg %c %p %.*s",
(char) d->room, conn,
conn->content_len - 4, conn->content + 4);
}
static void broadcast(struct mg_connection *nc, const char *msg, size_t len) {
struct mg_connection *c;
char buf[500];
snprintf(buf, sizeof(buf), "%p %.*s", nc, (int) len, msg);
for (c = mg_next(nc->mgr, NULL); c != NULL; c = mg_next(nc->mgr, c)) {
mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, buf, strlen(buf));
}
}
static int ev_handler(struct mg_connection *conn, enum mg_event ev) {
static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
struct http_message *hm = (struct http_message *) ev_data;
struct websocket_message *wm = (struct websocket_message *) ev_data;
switch (ev) {
case MG_REQUEST:
if (conn->is_websocket) {
handle_websocket_message(conn);
return MG_TRUE;
} else {
mg_send_file(conn, "index.html", NULL); // Return MG_MORE after!
return MG_MORE;
case NS_HTTP_REQUEST:
/* Usual HTTP request - serve static files */
mg_serve_http(nc, hm, s_http_server_opts);
nc->flags |= NSF_SEND_AND_CLOSE;
break;
case NS_WEBSOCKET_HANDSHAKE_DONE:
/* New websocket connection. Tell everybody. */
broadcast(nc, "joined", 6);
break;
case NS_WEBSOCKET_FRAME:
/* New websocket message. Tell everybody. */
broadcast(nc, (char *) wm->data, wm->size);
break;
case NS_CLOSE:
/* Disconnect. Tell everybody. */
if (is_websocket(nc)) {
broadcast(nc, "left", 4);
}
case MG_WS_CONNECT:
// New websocket connection. Send connection ID back to the client.
conn->connection_param = calloc(1, sizeof(struct conn_data));
mg_websocket_printf(conn, WEBSOCKET_OPCODE_TEXT, "id %p", conn);
return MG_FALSE;
case MG_CLOSE:
free(conn->connection_param);
return MG_TRUE;
case MG_AUTH:
return MG_TRUE;
break;
default:
return MG_FALSE;
break;
}
}
int main(void) {
s_server = mg_create_server(NULL, ev_handler);
mg_set_option(s_server, "listening_port", "8080");
struct mg_mgr mgr;
struct mg_connection *nc;
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
printf("Started on port %s\n", mg_get_option(s_server, "listening_port"));
mg_mgr_init(&mgr, NULL);
nc = mg_bind(&mgr, s_http_port, ev_handler);
s_http_server_opts.document_root = ".";
mg_set_protocol_http_websocket(nc);
printf("Started on port %s\n", s_http_port);
while (s_signal_received == 0) {
mg_poll_server(s_server, 100);
mg_mgr_poll(&mgr, 200);
}
mg_destroy_server(&s_server);
mg_mgr_free(&mgr);
return 0;
}