introduce-mirror-test-protocol.patch

Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
Andy Green 2010-11-12 13:10:40 +00:00
parent 85ba32fcbf
commit fe2a0d2e88
2 changed files with 233 additions and 14 deletions

View file

@ -27,6 +27,20 @@
#include "../lib/libwebsockets.h"
/*
* This demo server shows how to use libwebsockets for one or more
* websocket protocols in the same server
*
* It defines the following websocket protocols:
*
* dumb-increment-protocol: once the socket is opened, an incrementing
* ascii string is sent down it every 50ms.
* If you send "reset\n" on the websocket, then
* the incrementing number is reset to 0.
*
*/
#define LOCAL_RESOURCE_PATH "/usr/share/libwebsockets-test-server"
static int port = 7681;
static int use_ssl = 0;
@ -95,6 +109,7 @@ callback_dumb_increment(struct libwebsocket * wsi,
break;
case LWS_CALLBACK_RECEIVE:
fprintf(stderr, "rx %d\n", len);
if (len < 6)
break;
if (strcmp(in, "reset\n") == 0)
@ -109,6 +124,91 @@ callback_dumb_increment(struct libwebsocket * wsi,
}
/* lws-mirror_protocol */
#define MAX_MESSAGE_QUEUE 64
const int MAX_COMMUNE_MEMBERS = 20;
struct per_session_data__lws_mirror {
struct libwebsocket * wsi;
int ringbuffer_tail;
};
struct a_message {
struct per_session_data * sender;
void * payload;
size_t len;
};
static struct a_message ringbuffer[MAX_MESSAGE_QUEUE];
static int ringbuffer_head;
struct per_session_data * all_members;
static int
callback_lws_mirror(struct libwebsocket * wsi,
enum libwebsocket_callback_reasons reason,
void * user, void *in, size_t len)
{
int n;
char buf[LWS_SEND_BUFFER_PRE_PADDING + 512 +
LWS_SEND_BUFFER_POST_PADDING];
unsigned char *p = (unsigned char *)&buf[LWS_SEND_BUFFER_PRE_PADDING];
struct per_session_data__lws_mirror * pss = user;
switch (reason) {
case LWS_CALLBACK_ESTABLISHED:
pss->wsi = wsi;
pss->ringbuffer_tail = ringbuffer_head;
break;
case LWS_CALLBACK_SEND:
/* send everything that's pending */
while (pss->ringbuffer_tail != ringbuffer_head) {
n = libwebsocket_write(wsi,
(unsigned char *)ringbuffer[pss->ringbuffer_tail].payload +
LWS_SEND_BUFFER_PRE_PADDING,
ringbuffer[pss->ringbuffer_tail].len,
LWS_WRITE_TEXT);
if (n < 0) {
fprintf(stderr, "ERROR writing to socket");
exit(1);
}
if (pss->ringbuffer_tail == (MAX_MESSAGE_QUEUE - 1))
pss->ringbuffer_tail = 0;
else
pss->ringbuffer_tail++;
}
break;
case LWS_CALLBACK_RECEIVE:
// fprintf(stderr, "Received %d bytes payload\n", (int)len);
ringbuffer[ringbuffer_head].payload =
malloc(LWS_SEND_BUFFER_PRE_PADDING + len +
LWS_SEND_BUFFER_POST_PADDING);
ringbuffer[ringbuffer_head].len = len;
ringbuffer[ringbuffer_head].sender = pss;
memcpy(ringbuffer[ringbuffer_head].payload +
LWS_SEND_BUFFER_PRE_PADDING, in, len);
if (ringbuffer_head == (MAX_MESSAGE_QUEUE - 1))
ringbuffer_head = 0;
else
ringbuffer_head++;
break;
default:
break;
}
return 0;
}
/* list of supported protocols and callbacks */
static const struct libwebsocket_protocols protocols[] = {
@ -123,6 +223,12 @@ static const struct libwebsocket_protocols protocols[] = {
.per_session_data_size =
sizeof(struct per_session_data__dumb_increment),
},
{
.name = "lws-mirror-protocol",
.callback = callback_lws_mirror,
.per_session_data_size =
sizeof(struct per_session_data__lws_mirror),
},
{ /* end of list */
.callback = NULL
}

View file

@ -15,48 +15,161 @@ reset the number.<br><br>
<tr>
<td align=center><input type=button id=offset value="Reset counter" onclick="reset();" ></td>
<td width=100 align=center><div id=number> </div></td>
<td id=statustd align=center><div id=wsstatus>Not initialized</div></td>
<td id=wsdi_statustd align=center><div id=wsdi_status>Not initialized</div></td>
</tr>
</table>
<h2>libwebsockets "lws-mirror-protocol" test applet</h2>
Use the mouse to draw on the canvas below -- all other browser windows open
on this page see your drawing in realtime and you can see any of theirs as
well.
<p>
The lws-mirror protocol doesn't interpret what is being sent to it, it just
re-sends it to every other websocket it has a connection with using that
protocol, including the guy who sent the packet.
<br><br>
<table>
<tr>
<td>Drawing color:
<select id="color" onchange="update_color();">
<option value=#000000>Black</option>
<option value=#0000ff>Blue</option>
<option value=#20ff20>Green</option>
<option value=#802020>Dark Red</option>
</select>
</td>
<td id=wslm_statustd align=center><div id=wslm_status>Not initialized</div></td>
</tr>
<tr>
<td colspan=2 width=500 align=center style="background-color: #e0e0e0;"><div id=wslm_drawing> </div></td>
</tr>
</table>
<script>
var pos = 0;
var websocket_ads;
function get_appropriate_ws_url(ads)
{
/*
* We open the websocket encrypted if this page came on an
* https:// url itself, otherwise unencrypted
*/
if (document.URL.substring(0, 5) == "https")
websocket_ads = "wss://127.0.0.1:7681";
return "wss://"+ads;
else
websocket_ads = "ws://127.0.0.1:7681"
return "ws://"+ads;
}
/* dumb increment protocol */
var socket = new WebSocket(websocket_ads, "dumb-increment-protocol");
var socket_di = new WebSocket(get_appropriate_ws_url("127.0.0.1:7681"),
"dumb-increment-protocol");
try {
socket.onopen = function() {
statustd.style.backgroundColor = "#40ff40";
wsstatus.textContent = " websocket connection opened ";
socket_di.onopen = function() {
wsdi_statustd.style.backgroundColor = "#40ff40";
wsdi_status.textContent = " websocket connection opened ";
}
socket.onmessage =function got_packet(msg) {
socket_di.onmessage =function got_packet(msg) {
number.textContent = msg.data + "\n";
}
socket.onclose = function(){
statustd.style.backgroundColor = "#ff4040";
wsstatus.textContent = " websocket connection closed ";
socket_di.onclose = function(){
wsdi_statustd.style.backgroundColor = "#ff4040";
wsdi_status.textContent = " websocket connection closed ";
}
} catch(exception) {
alert('<p>Error'+exception);
alert('<p>Error' + exception);
}
function reset() {
socket.send("reset\n");
socket_di.send("reset\n");
}
/* lws-mirror protocol */
var down = 0;
var no_last = 1;
var last_x, last_y;
var ctx;
var socket_lm = new WebSocket(get_appropriate_ws_url("127.0.0.1:7681"),
"lws-mirror-protocol");
var color = "#000000";
try {
socket_lm.onopen = function() {
wslm_statustd.style.backgroundColor = "#40ff40";
wslm_status.textContent = " websocket connection opened ";
}
socket_lm.onmessage =function got_packet(msg) {
i = msg.data.split(' ');
if (i[0] == 'd') {
ctx.strokeStyle = i[1];
ctx.beginPath();
ctx.moveTo(i[2], i[3]);
ctx.lineTo(i[4], i[5]);
ctx.stroke();
}
}
socket_lm.onclose = function(){
wslm_statustd.style.backgroundColor = "#ff4040";
wslm_status.textContent = " websocket connection closed ";
}
} catch(exception) {
alert('<p>Error' + exception);
}
var canvas = document.createElement('canvas');
canvas.height = 300;
canvas.width = 480;
ctx = canvas.getContext("2d");
document.getElementById('wslm_drawing').appendChild(canvas);
canvas.addEventListener('mousemove', ev_mousemove, false);
canvas.addEventListener('mousedown', ev_mousedown, false);
canvas.addEventListener('mouseup', ev_mouseup, false);
function update_color() {
color = document.getElementById("color").value;
}
function ev_mousedown (ev) {
down = 1;
}
function ev_mouseup(ev) {
down = 0;
no_last = 1;
}
function ev_mousemove (ev) {
var x, y;
x = ev.offsetX;
y = ev.offsetY;
if (!down)
return;
if (no_last) {
no_last = 0;
last_x = x;
last_y = y;
return;
}
socket_lm.send("d " + color + " " + last_x + " " + last_y + " " + x + ' ' + y);
last_x = x;
last_y = y;
}
</script>
</body>