3

ネイティブ C++ WebSocket (www.websocket.org) クライアントから socket.io サーバーとデータを交換できません。組み込みシステムから WebSocket クライアントを実行しているため、Boost に基づくソリューションは必要ないことに注意してください (軽量である必要があります)。

LWS_WRITE_TEXT と LWS_WRITE_HTTP (パディングなし) の両方のモードを試しました。セキュア ソケットを使用していません (つまり、wss または SSL 証明書を使用していません)。

myServer.js:

var io = require('socket.io').listen(80);

io.configure('production', function(){
  io.enable('browser client etag');
  io.set('log level', 3);
  io.set('transports', ['websocket']);
});

io.configure('development', function(){
  io.set('log level', 3);
  io.set('transports', ['websocket']);
});

io.sockets.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

開始点として libwebsockets-test-echo.cpp サンプル コードを拡張し、クライアントとサーバーの両方が WebSockets C++ API を使用する場合に正常に動作するようにしました。ただし、socket.io サーバーに接続すると、サーバー コンソールは次のように報告します: warn - unknown transport: "undefined" 。

client.cpp:

...
    struct per_session_data__echo {
    // for LWS_WRITE_TEXT mode, PRE_PADDING is defined to LWS_SEND_BUFFER_PRE_PADDING and POST_PADDING is LWS_SEND_BUFFER_POST_PADDING, otherwise they're both set to 0.
    unsigned char buf[PRE_PADDING + 1400 + POST_PADDING];
    unsigned int len;
    unsigned int index;
};

static int callback_echo(struct libwebsocket_context *context,
    struct libwebsocket *wsi,
    enum libwebsocket_callback_reasons reason, void *user,
    void *in, size_t len)
{
    struct per_session_data__echo *pss = (struct per_session_data__echo *)user;
    int n;

    switch (reason) {
    case LWS_CALLBACK_CLIENT_ESTABLISHED:
        lwsl_notice("Client has connected\n");
        pss->index = 0;
        break;

    case LWS_CALLBACK_CLIENT_RECEIVE:
        lwsl_notice("Client RX: %s", (char *)in);
        break;

    case LWS_CALLBACK_CLIENT_WRITEABLE:
        /* we will send our packet... */
        pss->len = sprintf((char *)&pss->buf[LWS_SEND_BUFFER_PRE_PADDING], "hello from libwebsockets-test-echo client pid %d index %d\n", getpid(), pss->index++);
        lwsl_notice("Client TX: %s", &pss->buf[LWS_SEND_BUFFER_PRE_PADDING]);
        n = libwebsocket_write(wsi, &pss->buf[LWS_SEND_BUFFER_PRE_PADDING], pss->len, LWS_WRITE_TEXT);
        if (n < 0) {
            lwsl_err("ERROR %d writing to socket, hanging up\n", n);
            return -1;
        }
        if (n < (int)pss->len) {
            lwsl_err("Partial write\n");
            return -1;
        }
        break;
    default:
        break;
    }

    return 0;
}

static struct libwebsocket_protocols protocols[] = {
    /* first protocol must always be HTTP handler */
    {
        "my other event",      /* name */
        callback_echo,      /* callback */
        sizeof(struct per_session_data__echo),  /* per_session_data_size */
        0
    },
    {
        NULL, NULL, 0, 0       /* End of list */
    }
};

...

struct lws_context_creation_info info;
info.port = CONTEXT_PORT_NO_LISTEN;
info.iface = "eth0";
info.gid = -1;
info.uid = -1;
info.options = 0;
info.extensions = libwebsocket_get_internal_extensions();
info.protocols = protocols;

libwebsocket_context context_;
context_ = libwebsocket_create_context(&info);

libwebsocket *wsi_;
wsi_ = libwebsocket_client_connect(context_,
    "localhost",
    80, // port
    0, // "ws:" (no SSL)
    "/socket.io", // path
    "localhost", // host name
    "controller", // Socket origin name
    "my other event", // libwebsocket protocol name
    -1
    );

...
libwebsocket_callback_on_writable_all_protocol(&protocols_[0]);

...
int rc = 0;
unsigned int oldus = 0;
while (rc >= 0 && !forceExit_) {
    struct timeval tv;

    gettimeofday(&tv, NULL);

    if (((unsigned int)tv.tv_usec - oldus) > pollingRate_) {
        oldus = tv.tv_usec;
    }
    rc = libwebsocket_service(context_, 1000); // wait 1000 msec
    if (rc != 0) printf("rc=%d\n", rc);
}

...

「sudo node server.js」からの出力は次のとおりです。

  info  - socket.io started
  warn  - unknown transport: "undefined"

client.cpp コンソールからの出力は次のとおりです。これは、libwebsockets-test-echo.cpp によって使用されるコンテキスト ポート設定であり、websocket から websocket クライアントおよびサーバーへと機能します。接続が完了し、この出力が LWS_WRITE_TEXT モードと LWS_WRITE_HTTP モードの両方で同じであることに注意してください。

listening on port=0
listening on interface=eth0
lwsts[12960]: Initial logging level 7
lwsts[12960]: Library version: 1.3 502b994
lwsts[12960]:  Started with daemon pid 0
lwsts[12960]:  static allocation: 4488 + (16 x 1024 fds) = 20872 bytes
lwsts[12960]:  canonical_hostname = sogo
lwsts[12960]: context->protocols[0].name='my other event'
lwsts[12960]: LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS
lwsts[12960]: context->protocols[0].name='my other event'
lwsts[12960]: LWS_CALLBACK_PROTOCOL_INIT
lwsts[12960]: WebSocketClient::connect(): connecting to localhost:80 ...
sslCerts=0
protocolNameList='my other event'
connecting to address=localhost and port=80
lwsts[13340]: context->protocols[0].name='my other event'
lwsts[13340]: LWS_CALLBACK_ADD_POLL_FD
lwsts[13340]: context->protocols[0].name='my other event'
lwsts[13340]: LWS_CALLBACK_CLEAR_MODE_POLL_FD
lwsts[13340]: context->protocols[0].name='my other event'
lwsts[13340]: LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED
lwsts[13340]: context->protocols[0].name='my other event'
lwsts[13340]: LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER
lwsts[13340]: WebSocketClient::connect(): connected to localhost:80
lwsts[13340]: context->protocols[0].name='my other event'
lwsts[13340]: LWS_CALLBACK_SET_MODE_POLL_FD
lwsts[13340]: WebSocketClient::run(): running ...
lwsts[13340]: problems parsing header
lwsts[13340]: context->protocols[0].name='my other event'
lwsts[13340]: LWS_CALLBACK_DEL_POLL_FD
4

0 に答える 0