[Libwebsockets] libwebsocket problem

Wei, Catherine catherine.wei at commscope.com
Tue May 28 09:52:36 CEST 2019

Thanks, I will try your suggestion.
Another question about the usage of libwebsocket. Can you give some suggestion on how to use secure websocket?
I want to start a secure websocket server and so the client can request connection to the server by "wss://ip:port"?

Best regards,

-----Original Message-----
From: Andy Green <andy at warmcat.com> 
Sent: 2019年5月27日 13:25
To: Wei, Catherine <catherine.wei at commscope.com>; libwebsockets at ml.libwebsockets.org
Subject: Re: [Libwebsockets] libwebsocket problem

Message received from external source. Exercise caution when opening attachments, clicking links, or exchanging information.


On 5/27/19 4:52 AM, Wei, Catherine wrote:
> Yes, I think we have what you said.
> The server instance call
> int TServer::Initialize(int serverPort, bool allowRemoteClients,  
> const std::set<std::string>& supportedProtocols),  when it receives a 
> callback
> (reason: LWS_CALLBACK_ADD_POLL_FD), it will call
> "EventLoop->AddDescriptor() like below:
> int TServer::LwsCallback(lws* wsi, lws_callback_reasons reason, void* 
> user,  void* in,   size_t len) {
>    auto context = lws_get_context(wsi);
>    auto self = static_cast<TLwsBase*>(lws_context_user(context));
>    auto pollArgs = static_cast<const lws_pollargs*>(in);
>    if (!self->ShuttingDown) {
>      int result = 0;
>      if (self->HandleLwsCallback(wsi, reason, user, in, len, result)) 
> {
>        return result;
>      }
>    }
>    switch (reason) {
>      self->EventLoop.RemoveDescriptor(pollArgs->fd);
>      // Fall through
>      self->EventLoop.AddDescriptor(pollArgs->fd,
>                                    FromLwsEventMask(pollArgs->events),
>                                    IIOEventLoop::PRIORITY_NORMAL,
>                                    self);
>      break;
> ......
> }
> After adding the descriptor, we will handle the socket coming to the 
> file descirptor
> void TServer::HandleEvent(int fd, uint32_t event) {
>    lws_pollfd pollFdStruct = {
>      .fd = fd,
>      .events = ToLwsEventMask(event),
>      .revents = ToLwsEventMask(event)
>    };
>    lws_service_fd(LwsContext, &pollFdStruct); }
> The lws_service_fd() is what you called lws_service(), right?

You've basically hotwired your fd events up to lws_service_fd(), which is good if that's what you want.  But it's not enough.

Some things, eg, timeout handling, do not happen because of fd events... 
in fact you want timeouts to fire precisely when you have not been getting any fd events.

If you used the lws event loop, with the poll() backend each time around
lws_service() it will do the timeout processing... by default it waits for up to 1000ms before exiting and coming around again.

With the other lws event loop backends like libuv etc, lws sets up a 1Hz timer to do the timeout checking for you.

But with what you have here, where you participate in someone else's event loop, you must also manually ask for the timeout / periodic check stuff to be handled... look at the last part of the comment for

  * lws_service_fd() - Service polled socket with something waiting
  * \param context:	Websocket context
  * \param pollfd:	The pollfd entry describing the socket fd and which 
  *		happened, or NULL to tell lws to do only timeout servicing.
  * This function takes a pollfd that has POLLIN or POLLOUT activity and
  * services it according to the state of the associated
  * struct lws.
  * The one call deals with all "service" that might happen on a socket
  * including listen accepts, http files as well as websocket protocol.
  * If a pollfd says it has something, you can just pass it to
  * lws_service_fd() whether it is a socket handled by lws or not.
  * If it sees it is a lws socket, the traffic will be handled and
  * pollfd->revents will be zeroed now.
  * If the socket is foreign to lws, it leaves revents alone.  So you can
  * see if you should service yourself by checking the pollfd revents
  * after letting lws try to service it.
  * You should also call this with pollfd = NULL to just allow the
  * once-per-second global timeout checks; if less than a second since the last
  * check it returns immediately then.

If you also take care of that, you will find timeouts and ASYNC close start to magically work.


More information about the Libwebsockets mailing list