introduce-mirror-test-protocol.patch
Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
parent
85ba32fcbf
commit
fe2a0d2e88
2 changed files with 233 additions and 14 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Reference in a new issue