mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-26 12:14:56 +00:00
Merge dev branch code named Fossa as next stable Mongoose
This commit is contained in:
1 parent
28eb251ccd
commit
8927c9d22b
126 files changed
+162049
-8502
No files matched your search
@@ -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">
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
Reference in new issue
Block a user