首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >libwebsockets在接收后写入所有活动连接

libwebsockets在接收后写入所有活动连接
EN

Stack Overflow用户
提问于 2014-08-16 16:25:10
回答 2查看 2.8K关注 0票数 1

我正在摆弄一个libwebsocket教程,试图使它在通过给定协议从连接接收到消息后,向实现该协议的所有活动连接发送响应。我已经使用了函数libwebsocket_callback_all_protocol,但是它并没有按照我的想法从它的名字中执行我认为应该做的事情(我不太确定它在文档中做了什么)。

目标是打开两个网页,当其中一个网页发送信息时,结果将传递给两个网页。下面是我的代码-你会看到libwebsocket_callback_all_protocol是在main中调用的(我想它目前什么都不做...):

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <libwebsockets.h>
#include <string.h>

static int callback_http(struct libwebsocket_context * this,
                         struct libwebsocket *wsi,
                         enum libwebsocket_callback_reasons reason, void *user,
                         void *in, size_t len)
{
    return 0;
}

static int callback_dumb_increment(struct libwebsocket_context * this,
                                   struct libwebsocket *wsi,
                                   enum libwebsocket_callback_reasons reason,
                                   void *user, void *in, size_t len)
{

    switch (reason) {
        case LWS_CALLBACK_ESTABLISHED: // just log message that someone is connecting
            printf("connection established\n");
            break;
        case LWS_CALLBACK_RECEIVE: { // the funny part
            // create a buffer to hold our response
            // it has to have some pre and post padding. You don't need to care
            // what comes there, libwebsockets will do everything for you. For more info see
            // http://git.warmcat.com/cgi-bin/cgit/libwebsockets/tree/lib/libwebsockets.h#n597
            unsigned char *buf = (unsigned char*) malloc(LWS_SEND_BUFFER_PRE_PADDING + len +
                                                         LWS_SEND_BUFFER_POST_PADDING);

            int i;

            // pointer to `void *in` holds the incomming request
            // we're just going to put it in reverse order and put it in `buf` with
            // correct offset. `len` holds length of the request.
            for (i=0; i < len; i++) {
                buf[LWS_SEND_BUFFER_PRE_PADDING + (len - 1) - i ] = ((char *) in)[i];
            }

            // log what we recieved and what we're going to send as a response.
            // that disco syntax `%.*s` is used to print just a part of our buffer
            // http://stackoverflow.com/questions/5189071/print-part-of-char-array
            printf("received data: %s, replying: %.*s\n", (char *) in, (int) len,
                 buf + LWS_SEND_BUFFER_PRE_PADDING);

            // send response
            // just notice that we have to tell where exactly our response starts. That's
            // why there's `buf[LWS_SEND_BUFFER_PRE_PADDING]` and how long it is.
            // we know that our response has the same length as request because
            // it's the same message in reverse order.
            libwebsocket_write(wsi, &buf[LWS_SEND_BUFFER_PRE_PADDING], len, LWS_WRITE_TEXT);

            // release memory back into the wild
            free(buf);
            break;
        }
        default:
            break;
    }


    return 0;
}

static struct libwebsocket_protocols protocols[] = {
    /* first protocol must always be HTTP handler */
    {
        "http-only",   // name
        callback_http, // callback
        0,              // per_session_data_size
        0
    },
    {
        "dumb-increment-protocol", // protocol name - very important!
        callback_dumb_increment,   // callback
        0,                          // we don't use any per session data
        0

    },
    {
        NULL, NULL, 0, 0   /* End of list */
    }
};

int main(void) {
    // server url will be http://localhost:9000
    int port = 9000;
    const char *interface = NULL;
    struct libwebsocket_context *context;
    // we're not using ssl
    const char *cert_path = NULL;
    const char *key_path = NULL;
    // no special options
    int opts = 0;

    // create libwebsocket context representing this server
    struct lws_context_creation_info info;
    memset(&info, 0, sizeof info);   

    info.port = port;
    info.iface = interface;
    info.protocols = protocols;
    info.extensions = libwebsocket_get_internal_extensions();
    info.ssl_cert_filepath = cert_path;
    info.ssl_private_key_filepath = key_path;
    info.gid = -1;
    info.uid = -1;
    info.options = opts;
    info.user = NULL;
    info.ka_time = 0;
    info.ka_probes = 0;
    info.ka_interval = 0;

    /*context = libwebsocket_create_context(port, interface, protocols,
                                          libwebsocket_get_internal_extensions,
                                          cert_path, key_path, -1, -1, opts);
   */
    context = libwebsocket_create_context(&info);
    if (context == NULL) {
        fprintf(stderr, "libwebsocket init failed\n");
        return -1;
    }

    libwebsocket_callback_all_protocol(&protocols[1], LWS_CALLBACK_RECEIVE);

    printf("starting server...\n");

    // infinite loop, to end this server send SIGTERM. (CTRL+C)
    while (1) {
        libwebsocket_service(context, 50);
        // libwebsocket_service will process all waiting events with their
        // callback functions and then wait 50 ms.
        // (this is a single threaded webserver and this will keep our server
        // from generating load while there are not requests to process)
    }

    libwebsocket_context_destroy(context);

    return 0;
}
EN

回答 2

Stack Overflow用户

发布于 2015-01-26 22:06:15

我也有同样的问题,LWS_CALLBACK_ESTABLISHED上的libwebsocket_write生成了一些随机的段错误,所以使用邮件列表的libwebsocket开发者Andy Green告诉我正确的方法是使用libwebsocket_callback_on_writable_all_protocol,文件test-server/test-server.c在库源代码中显示了使用示例。

代码语言:javascript
复制
libwebsocket_callback_on_writable_all_protocol(libwebsockets_get_protocol(wsi))

它可以很好地通知所有实例,但它只在所有连接的实例中调用write方法,并不定义要发送的数据。您需要自己管理数据。样例源文件test-server.c显示了执行此操作的样例环形缓冲区。

http://ml.libwebsockets.org/pipermail/libwebsockets/2015-January/001580.html

希望能有所帮助。

票数 1
EN

Stack Overflow用户

发布于 2014-09-02 17:40:32

根据我从文档中快速获取的信息,为了向所有客户端发送消息,您应该做的是将客户端连接时可以访问的struct libwebsocket * wsi存储在某个位置(以向量、哈希图、数组等形式存储)。

然后,当您收到一条消息并希望广播它时,只需在所有wsi *实例上调用libwebsocket_write

不管怎样,这就是我要做的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25338324

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档