【C++】libwebsocketsライブラリの簡単なチュートリアル(ソースコード付き)

目次

1. よく使われるAPI

2. サーバー

3. クライアント

4. いくつかのピットを踏んだ


1. よく使われるAPI

(1) lws_create_context: 逆のコンテキストを作成し、WSを管理します

        lws_create_context は、WebSocket コンテキストの作成に使用される libwebsockets ライブラリ内の関数です。WebSocket コンテキストは、WebSocket に関連するすべての情報とステータスを含む構造です。WebSocket 接続を作成する前に、まず WebSocket コンテキストを作成する必要があります。lws_create_context 関数の役割は、WebSocket コンテキストを初期化し、WebSocket コンテキストへのポインターを返すことです。

(2) lws_context_destroy: コンテキストオブジェクトを破棄します。

        lws_context_destroy は、libwebsockets アプリケーション コンテキストを破棄するために使用される関数です。ソケット、スレッド、バッファなど、コンテキストに割り当てられたすべてのリソースを解放します。この関数を呼び出した後は、アプリケーションはコンテキストを使用できなくなるため、コンテキストが必要ない場合にのみこの関数を呼び出すようにしてください。

(3) lws_client_connect_via_info: WebSocketサーバーに接続します

        lws_client_connect_via_info は libwebsockets ライブラリの関数であり、その役割は、提供された接続情報を通じてクライアント接続を確立することです。この関数は、クライアント アプリケーションでサーバーに接続するために使用できます。 

具体的には、lws_client_connect_via_info 関数は次の情報を提供する必要があります。

1. http、https、websocket などの接続プロトコルの名前。

2. サーバーのホスト名または IP アドレス。

3. サーバーのポート番号。

4. SSL/TLS 証明書などの接続オプション

5. 接続ステータスを処理し、データを受信するためのコールバック関数。

これらの情報を提供することにより、lws_client_connect_via_info 関数はクライアント接続を確立し、コールバック関数を呼び出して接続ステータスを処理し、接続の確立後にデータを受信できます。

(4) lws_service: すべての未処理のイベントとデータを処理します

        libwebsockets ライブラリの lws_service は、すべての未処理のイベントとデータを処理する関数です。無限ループで実行され、処理する新しいイベントやデータがないか常にチェックされます。新しいイベントまたはデータが到着すると、対応するコールバック関数を呼び出してそれらを処理します。lws_service 関数は、libwebsockets ライブラリの最も重要な関数の 1 つであり、ネットワーク接続の安定性と信頼性を保証します。

(5) lws_callback_on_writable: サーバーがクライアントにデータを送信するように設定します。

        lws_callback_on_writable は libwebsockets ライブラリの関数で、WebSocket 接続の書き込み可能なコールバック関数をイベント ループに追加することを意味します。このコールバックは、接続のネットワーク バッファーが空になったときに起動されます。この関数は通常、WebSocket 接続でデータを送信するために使用されます。この関数を呼び出すと、ネットワーク バッファーが書き込み可能になったときにデータがすぐに送信されるようになり、ネットワークの送信効率が向上します。

(6) よく使われる構造

    struct lws // WebSocket 接続ハンドル
    struct lws_context // WebSocket プロセッサ
    struct lws_context_creation_info // コンテキスト パラメータ
    struct lws_protocols // プロトコル層トランスポート ハンドル
    void* m_pUser; // コールバック オブジェクトを返す
    struct lws_client_connect_info // 接続パラメータ

2. サーバー

libwebsockets を使用して WebSocket サーバーを作成する簡単な手順は次のとおりです。

(1) libwebsockets ライブラリのインストール: 公式 Web サイト (https://libwebsockets.org/) からライブラリの最新バージョンをダウンロードできます。

libwebsockets ライブラリは、次のコマンドでインストールできます。

sudo apt-get install libwebsockets-dev

(2) WebSocketサーバーの作成

基本的な手順:

a. すべてのクライアント接続を管理する libwebsocket_context オブジェクトを作成します。

b. サーバーのプロトコルとポート番号を設定します。

c. クライアントからのメッセージを処理するコールバック関数を作成します。

d. サーバーを起動し、クライアントが接続するまで待ちます。

クライアント接続の処理: クライアントがサーバーに接続するときは、接続を処理するコードを記述する必要があります。これには、クライアントの認証、メッセージの処理、接続の終了が含まれます。

メッセージの送信: libwebsocket ライブラリの関数を使用して、クライアントにメッセージを送信できます。

単純な WebSocket サーバーのコードは次のとおりです。

libwebsocket オープン ソース ライブラリでは、lws_service コールバック関数のパラメータの意味は次のとおりです。

1. wsi: websocket インスタンス。現在処理中の websocket 接続を示します。

2.reason: 接続を閉じた理由コード。接続が閉じられていない場合、このパラメータは 0 です。

3. user: lws_callback_on_writable 関数を使用して設定できるユーザー データ。

4. in: 受信データバッファ。

5. len: 受信データの長さ。

6. flags: 接続ステータスおよびその他の情報を示すために使用されるフラグ ビット。

7. out: データバッファを送信します。

8. out_len: 送信データ長。

9.reserved: 一時的に使用されない予約済みパラメータ。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libwebsockets.h>

static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
{
    return 0;
}

static int callback_websocket(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
{
    switch (reason) {
        case LWS_CALLBACK_ESTABLISHED:
            printf("WebSocket connection established\n");
            break;
        case LWS_CALLBACK_RECEIVE:
            printf("Received data: %s\n", (char *)in);
            break;
        case LWS_CALLBACK_CLOSED:
            printf("WebSocket connection closed\n");
            break;
        default:
            break;
    }
    return 0;
}


//注册协议,一种协议,对应一套处理方案(类似驱动中的设备树)
static struct lws_protocols protocols[] = {
    {
        "http",
        callback_http,
        0,
        0,
    },
    {
        "websocket",
        callback_websocket,
        0,
        0,
    },
    { NULL, NULL, 0, 0 } /* end of list */
};

int main(int argc, char **argv)
{
    struct lws_context_creation_info info;
    struct lws_context *context;
    int port = 9000;

    memset(&info, 0, sizeof(info));
    info.port = port;
    info.protocols = protocols;

    context = lws_create_context(&info);

    if (!context) {
        printf("Error creating WebSocket context\n");
        return 1;
    }

    printf("WebSocket server started on port %d\n", port);

    while (1) {
        lws_service(context, 50);
    }

    lws_context_destroy(context);

    return 0;
}

(3) サーバーをコンパイルして実行する

サーバーは次のコマンドでコンパイルできます。

gcc -o server server.c -lwebsockets

次にサーバーを実行します。
 

./server

WebSocket サーバーが起動したので、ブラウザーまたは他の WebSocket クライアントを使用して WebSocket サーバーに接続できます。

上記は、libwebsockets ライブラリを使用して WebSocket サーバーを作成するための簡単なチュートリアルです。お役に立てば幸いです。

3. クライアント

(1) 基本的な手順:

A. libwebsocket ライブラリのヘッダー ファイルをコードに導入します。

#include <libwebsockets.h>

B. WebSocket 接続を管理するための lws_context オブジェクトを作成します。

struct lws_context* context;

C. 接続パラメータ構造を定義し、接続情報を設定します。

struct lws_client_connect_via_info connect_info = {
    .context = context,
    .address = "192.168.12.226",
    .port = 8081,
    .path = "/",
    .host = "192.168.12.226",
    .origin = "http://192.168.12.226",
    .protocol = NULL,
    .user = NULL,
    .password = NULL
};

D. lws_client_connect_via_info() 関数を使用して WebSocket サーバーに接続します。

lws* ws_client = lws_client_connect_via_info(&connect_info);

E. 接続が成功したら、lws_write() 関数を使用してサーバーにメッセージを送信できます。

char *message = "Hello, WebSocket Server!";
lws_write(ws_client, (unsigned char *)message, strlen(message), LWS_WRITE_TEXT);

F. 最後に、プログラムの最後で、lws_context_destroy() 関数を使用してリソースを解放します。

lws_context_destroy(context);

(2) 以下は、libwebsockets ライブラリを使用して基本的な WebSocket クライアントを作成するためのサンプル コードです。

lws_client_connect_via_info は、指定された接続情報を使用して WebSocket サーバーに接続する関数です。接続情報構造体へのポインタを引数として受け取り、接続ハンドルへのポインタを返します。接続情報構造には、サーバーのアドレス、ポート番号、プロトコルなど、接続に関する必要な情報がすべて含まれています。この機能を使用すると、WebSocket サーバーに簡単に接続して通信を開始できます。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libwebsockets.h>

static int callback_websocket(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len)
{
    switch (reason) {
        case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
            fprintf(stderr, "Error connecting to server\n");
            break;
        case LWS_CALLBACK_CLIENT_ESTABLISHED:
            fprintf(stderr, "Connected to server\n");
            break;
        case LWS_CALLBACK_CLIENT_RECEIVE:
            fprintf(stderr, "Received data: %s\n", (char *)in);
            break;
        case LWS_CALLBACK_CLOSED:
            fprintf(stderr, "Disconnected from server\n");
            break;
        default:
            break;
    }

    return 0;
}

int main(int argc, char **argv)
{
    struct lws_context *context;
    struct lws *websocket;
    struct lws_client_connect_info connect_info;

    memset(&connect_info, 0, sizeof(connect_info));
    connect_info.context = context;
    connect_info.address = "localhost";
    connect_info.port = 8000;
    connect_info.path = "/";
    connect_info.host = connect_info.address;
    connect_info.origin = connect_info.address;
    connect_info.protocol = NULL;
    connect_info.ssl_connection = 0;

    struct lws_protocols protocols[] = {
        { "default", callback_websocket, 0, 0 },
        { NULL, NULL, 0, 0 }
    };

    context = lws_create_context(NULL, NULL, protocols, NULL, NULL, NULL, NULL, -1, -1, 0);

    if (context == NULL) {
        fprintf(stderr, "Error creating context\n");
        return 1;
    }

    websocket = lws_client_connect_via_info(&connect_info);

    if (websocket == NULL) {
        fprintf(stderr, "Error connecting to server\n");
        return 1;
    }

    while (lws_service(context, 0) >= 0);

    lws_context_destroy(context);

    return 0;
}

このサンプル コードは、WebSocket クライアントを作成し、ポート 8000 でローカルホストに接続し、受信したデータを出力します。connect_info.address と connect_info.port を変更して、他の WebSocket サーバーに接続できます。

main() 関数では、まず接続情報構造体 connect_info を設定し、次に lws_context オブジェクトを作成します。次に、lws_client_connect_via_info() を呼び出して WebSocket サーバーに接続し、while ループ内で lws_service() を使用して受信データまたはイベントを処理します。最後に、lws_context オブジェクトを破棄し、プログラムが正常に終了したことを示す 0 を返します。

4. いくつかのピットを踏んだ

(1) コンパイル時に、「libwebsocket ライブラリの lws-misc.h 変数 humanize_schema_si のサイズが不明です」というエラーが報告されます。

解決策:通常、Linux コンパイラーを使用する場合、これはエラーではありませんが、vs はエラーを報告します。これは、vs のセキュリティと構文チェック ルールが原因で発生するはずです。

したがって、Windows コンパイラを使用する場合は、それを変更するだけです。

 (2) サーバーに接続するクライアントの名前は、サーバーの名前と一致していることを忘れないでください。そうでないと接続できません。

おすすめ

転載: blog.csdn.net/bigger_belief/article/details/131111430