參考資訊:
https://github.com/iamscottmoyers/simple-libwebsockets-example
server.c
#include <stdio.h>
#include <string.h>
#include <libwebsockets.h>
#define EXAMPLE_RX_BUFFER_BYTES 255
#define LEN (LWS_SEND_BUFFER_PRE_PADDING + EXAMPLE_RX_BUFFER_BYTES + LWS_SEND_BUFFER_POST_PADDING)
struct payload {
unsigned char data[LEN];
size_t len;
} received_payload;
enum protocols {
PROTOCOL_HTTP = 0,
PROTOCOL_EXAMPLE,
PROTOCOL_COUNT
};
static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
{
switch (reason) {
case LWS_CALLBACK_HTTP:
lws_serve_http_file(wsi, "main.htm", "text/html", NULL, 0);
break;
}
return 0;
}
static int callback_example( struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len )
{
switch (reason) {
case LWS_CALLBACK_RECEIVE:
memcpy(&received_payload.data[LWS_SEND_BUFFER_PRE_PADDING], in, len);
received_payload.len = len;
lws_callback_on_writable_all_protocol(lws_get_context(wsi), lws_get_protocol(wsi));
break;
case LWS_CALLBACK_SERVER_WRITEABLE:
lws_write(wsi, &received_payload.data[LWS_SEND_BUFFER_PRE_PADDING], received_payload.len, LWS_WRITE_TEXT);
break;
}
return 0;
}
static struct lws_protocols protocols[] =
{
{
"http-only",
callback_http,
0,
0,
},
{
"example-protocol",
callback_example,
0,
EXAMPLE_RX_BUFFER_BYTES,
},
{
NULL,
NULL,
0,
0
}
};
int main(int argc, char *argv[])
{
struct lws_context_creation_info info = { 0 };
info.port = 8000;
info.protocols = protocols;
info.gid = -1;
info.uid = -1;
struct lws_context *context = lws_create_context(&info);
while (1) {
lws_service(context, 1000000);
}
lws_context_destroy(context);
return 0;
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libwebsockets.h>
#define EXAMPLE_TX_BUFFER_BYTES 255
#define LEN (LWS_SEND_BUFFER_PRE_PADDING + EXAMPLE_TX_BUFFER_BYTES + LWS_SEND_BUFFER_POST_PADDING)
enum protocols {
PROTOCOL_EXAMPLE = 0,
PROTOCOL_COUNT
};
static struct lws *web_socket = NULL;
static int callback_example(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
{
size_t n = 0;
unsigned char buf[LEN];
unsigned char *p = &buf[LWS_SEND_BUFFER_PRE_PADDING];
switch (reason) {
case LWS_CALLBACK_CLIENT_ESTABLISHED:
lws_callback_on_writable(wsi);
break;
case LWS_CALLBACK_CLIENT_WRITEABLE:
n = sprintf((char *)p, "%s", "Hello, world!");
lws_write(wsi, p, n, LWS_WRITE_TEXT);
break;
case LWS_CALLBACK_CLIENT_CLOSED:
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
web_socket = NULL;
break;
}
return 0;
}
static struct lws_protocols protocols[] = {
{
.name = "example-protocol",
.callback = callback_example,
.per_session_data_size = 0,
.rx_buffer_size = 0,
.id = 0,
.user = NULL,
.tx_packet_size = 0
},
{
NULL,
NULL,
0,
0
}
};
int main(int argc, char *argv[])
{
struct lws_context_creation_info info = { 0 };
info.port = CONTEXT_PORT_NO_LISTEN;
info.protocols = protocols;
info.gid = -1;
info.uid = -1;
time_t old = 0;
struct timeval tv;
struct lws_context *context = lws_create_context(&info);
while( 1 ) {
gettimeofday(&tv, NULL);
if (!web_socket && tv.tv_sec != old) {
struct lws_client_connect_info ccinfo = { 0 };
ccinfo.context = context;
ccinfo.address = "localhost";
ccinfo.port = 8000;
ccinfo.path = "/";
ccinfo.host = lws_canonical_hostname(context);
ccinfo.origin = "origin";
ccinfo.protocol = protocols[PROTOCOL_EXAMPLE].name;
web_socket = lws_client_connect_via_info(&ccinfo);
}
if (tv.tv_sec != old) {
lws_callback_on_writable(web_socket);
old = tv.tv_sec;
}
lws_service(context, 250);
}
lws_context_destroy(context);
return 0;
}
main.htm
<!DOCTYPE html>
<html>
<title>Websocket example</title>
<script>
var socket = new WebSocket("ws://" + document.domain + ':' + location.port, "example-protocol");
function update(msg) { document.getElementById("num").innerHTML = msg; }
socket.onopen = function() { console.log("socket open"); update("open"); }
socket.onclose = function() { console.log("socket close"); update("closed"); }
socket.onmessage = function(msg) { console.log("socket message: " + msg.data); update(msg.data); }
</script>
<body>
<p id="num"></p>
</body>
</html>
編譯、執行
$ gcc client.c -o client -lwebsockets $ gcc client.c -o client -lwebsockets $ ./server & $ ./client &
開啟網頁即可