程序代码如下:
Code: Select all
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libwebsockets.h>
#include <unistd.h>
static struct lws *wsi = NULL;
static int established = 0;
static int isBreak = 0;
static int stop = 0;
int UnmarshalURL(const char *_url, char *_protocol, char *_host, int *_port, char *path)
{
char url[256];
strncpy(url, _url, sizeof(url) - 1);
url[sizeof(url) - 1] = '\0';
char *pslash = strstr(url, "//");
if (pslash)
{
strncpy(_protocol, url, pslash - url);
_protocol[pslash - url] = '\0';
strcpy(url, pslash + 2);
}
pslash = strchr(url, ':');
if (!pslash)
{
*_port = -1;
pslash = strchr(url, '/');
if (!pslash)
{
strcpy(_host, url);
}
else
{
strncpy(_host, url, pslash - url);
_host[pslash - url] = '\0';
strcpy(path, pslash);
}
}
else
{
strncpy(_host, url, pslash - url);
_host[pslash - url] = '\0';
strcpy(url, pslash + 1);
pslash = strchr(url, '/');
if (!pslash)
{
*_port = atoi(url);
}
else
{
char portStr[16];
strncpy(portStr, url, pslash - url);
portStr[pslash - url] = '\0';
*_port = atoi(portStr);
strcpy(path, pslash);
}
}
return 0;
}
static int IsfirstMsg = 1;
static int DeviceId = 1;
static char writeBuffer[128];
int ws_callback(struct lws *_wsi, enum lws_callback_reasons _reasons, void *_user, void *_in, size_t _len)
{
char buffer[2560] = {0};
int len = 0;
switch (_reasons)
{
case LWS_CALLBACK_CLIENT_ESTABLISHED:
printf("Connection established\n");
lws_callback_on_writable(_wsi);
break;
case LWS_CALLBACK_CLIENT_CLOSED:
isBreak = 1;
printf("Connection closed\n");
break;
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
printf("Connection error\n");
break;
case LWS_CALLBACK_CLIENT_RECEIVE:
memcpy(buffer, _in, _len);
printf("Received from server: %s\n", buffer);
if (strcmp(buffer, "openCamera") == 0)
{
printf("Opening camera...\n");
strcpy(writeBuffer, "CameraOK");
lws_callback_on_writable(_wsi);
}
usleep(1000 * 1000);
break;
case LWS_CALLBACK_CLIENT_WRITEABLE:
if (stop)
break;
if (IsfirstMsg)
{
snprintf(writeBuffer, sizeof(writeBuffer), "id:%d", DeviceId);
IsfirstMsg = 0;
}
printf("Writing data: %s\n", writeBuffer);
len = lws_write(_wsi, (unsigned char *)writeBuffer, strlen(writeBuffer), LWS_WRITE_TEXT);
printf("Write length: %d\n", len);
break;
default:
break;
}
return 0;
}
void *heartbeat_thread_func(void *arg)
{
while (1)
{
if (!IsfirstMsg)
{
strcpy(writeBuffer, "beat");
lws_callback_on_writable(wsi);
}
sleep(30);
}
return NULL;
}
int main(int argc, char **argv)
{
if (argc < 2 || argc > 3)
{
printf("Usage: %s <url> [device_id]\n", argv[0]);
return -1;
}
char protocol[16] = {0}, host[128] = {0}, path[128] = {0};
int port = 0;
UnmarshalURL(argv[1], protocol, host, &port, path);
if (argc == 3)
DeviceId = atoi(argv[2]);
else
DeviceId = 1;
int ssl = (strcmp(protocol, "wss") == 0) ? 1 : 0;
struct lws_context_creation_info info = {0};
struct lws_client_connect_info ci = {0};
struct lws_context *context;
struct lws_protocols protocols[] = {
{"ws-client", ws_callback, 0, 5120},
{NULL, NULL, 0, 0}
};
info.protocols = protocols;
info.port = CONTEXT_PORT_NO_LISTEN;
info.options = ssl ? LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT : 0;
context = lws_create_context(&info);
if (!context)
{
printf("Failed to create context\n");
return -1;
}
ci.context = context;
ci.address = host;
ci.port = port;
ci.path = path;
ci.host = ci.address;
ci.origin = ci.address;
ci.ssl_connection = ssl ? (LCCSCF_USE_SSL | LCCSCF_ALLOW_SELFSIGNED) : 0;
ci.protocol = protocols[0].name;
ci.pwsi = &wsi;
lws_client_connect_via_info(&ci);
pthread_t thread;
if (pthread_create(&thread, NULL, heartbeat_thread_func, NULL) != 0)
{
printf("Failed to create heartbeat thread\n");
return -1;
}
while (!isBreak)
{
lws_service(context, 500);
}
lws_context_destroy(context);
return 0;
}