[Libwebsockets] Got "WSI_STATE_DEAD_SOCKET" when try to connect "echo.websocket.org"

"Andy Green (林安廸)" andy at warmcat.com
Wed Jan 16 17:40:44 CET 2013


On 17/01/13 00:35, the mail apparently from "Andy Green (林安廸)" included:
> On 16/01/13 23:19, the mail apparently from 杨世玲 included:
>> Hello everyone,
>>
>> I'm try to write a client of websocket.
>> There is a web demo from websocket.org,
>> http://www.websocket.org/echo.html.
>> It using "ws://echo.websocket.org/"
>>
>> but the instance of libwebsocket has a state "WSI_STATE_DEAD_SOCKET"
>> when call libwebsocket_write.
>>
>> did I miss something important? thank you very much.
>
> If you add this -->
>
> lws_set_log_level(511, NULL);
>
> you'll get maximum debug from the library coming on stderr
>
> The problem is it doesn't like the headers coming back from that server...
>
> [1358352836:7753] PARSER: libwebsocket_client_handshake missing required
> header(s)
>
> ... and that's because until now libwebsockets insists to select a
> protocol.
>
> Here is a small patch on libwebsockets that gets you past that, I'll do
> it properly tomorrow
>
> diff --git a/lib/client.c b/lib/client.c
> index 027fb77..473b144 100644
> --- a/lib/client.c
> +++ b/lib/client.c
> @@ -341,9 +341,10 @@ lws_client_interpret_server_handshake(struct
> libwebsocket_context *context,
>                  if (!wsi->utf8_token[WSI_TOKEN_HTTP].token_len ||
>                          !wsi->utf8_token[WSI_TOKEN_UPGRADE].token_len ||
>                          !wsi->utf8_token[WSI_TOKEN_CHALLENGE].token_len ||
> -                       !wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len ||
> -                       (!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len &&
> -                       wsi->c_protocol != NULL)) {
> +                       !wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len
> // ||
> +//                     (!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len &&
> +//                     wsi->c_protocol != NULL)
> +                       ) {
>                          lwsl_parser("libwebsocket_client_handshake "
>                                          "missing required header(s)\n");
>                          pkt[len] = '\0';
> @@ -396,11 +397,12 @@ lws_client_interpret_server_handshake(struct
> libwebsocket_context *context,
>              !wsi->utf8_token[WSI_TOKEN_CONNECTION].token_len ||
>              !wsi->utf8_token[WSI_TOKEN_ACCEPT].token_len ||
>              (!wsi->utf8_token[WSI_TOKEN_NONCE].token_len &&
> -                                  wsi->ietf_spec_revision == 4) ||
> -           (!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len &&
> -                                                   wsi->c_protocol !=
> NULL)) {
> +                                  wsi->ietf_spec_revision == 4) //||
> +//         (!wsi->utf8_token[WSI_TOKEN_PROTOCOL].token_len &&
> +//                                                 wsi->c_protocol !=
> NULL)
> +) {
>                  lwsl_parser("libwebsocket_client_handshake "
> -                                       "missing required header(s)\n");
> +                                       "missing required header(s)
> revision=%d\n", wsi->ietf_spec_revision);
>                  pkt[len] = '\0';
>                  lwsl_parser("%s", pkt);
>                  goto bail3;
>
>
> Your code is able to loop and send then, but there are some problems.
>
>   - you can't print the buffer you sent after sending it.  It's modified
> in place and destroyed by the send action.  You can print the copy in
> tbuf2 instead
>
>   - it's ok for initial test but sending should be done using the
> LWS_CALLBACK_CLIENT_WRITEABLE callback and
> libwebsocket_callback_on_writable(this, wsi); to guarantee it can't block
>
>   - since no protocol is defined it will use protocol 0 for callbacks
>
>   - I didn't see any rx coming, I'll look further into it.

Oh I see the problem immediately now I look

You need the callback

case LWS_CALLBACK_CLIENT_RECEIVE:

LWS_CALLBACK_RECEIVE is for server rx.

With that changed (and the library patch to allow no protocol...) you 
are working ^^

send msg [test msg 45], 0
rx 13 '[test msg 44]'
loop next 0
[1358354296:9755] PARSER: written 19 bytes to client
send msg [test msg 46], 0
rx 13 '[test msg 45]'
loop next 0
[1358354297:4861] PARSER: written 19 bytes to client
send msg [test msg 47], 0
rx 13 '[test msg 46]'
loop next 0
[1358354297:4862] PARSER: written 19 bytes to client
send msg [test msg 48], 0
rx 13 '[test msg 47]'
loop next 0
[1358354298:0000] PARSER: written 19 bytes to client
send msg [test msg 49], 0
rx 13 '[test msg 48]'
loop next 0
[1358354298:0001] PARSER: written 19 bytes to client
send msg [test msg 50], 0
...

-Andy

> -Andy
>
>> so here is my code in C++ using libwebsockets.
>>
>> #include <iostream>
>>
>> #include <libwebsockets.h>
>>
>> static int
>>
>> callback_socketio(struct libwebsocket_context *_this,
>>
>>                    struct libwebsocket *wsi,
>>
>>                    enum libwebsocket_callback_reasons reason,
>>
>>                    void *user, void *in, size_t len)
>>
>> {
>>
>>      switch (reason) {
>>
>>          case LWS_CALLBACK_CLOSED:
>>
>>              fprintf(stderr, "closed \n");
>>
>>              break;
>>
>>
>>
>>          case LWS_CALLBACK_CLIENT_ESTABLISHED:
>>
>>              libwebsocket_callback_on_writable(_this, wsi);
>>
>>              fprintf(stderr, "client established\n");
>>
>>              break;
>>
>>          case LWS_CALLBACK_RECEIVE:
>>
>>              fprintf(stderr, "rx %d '%s' \n", (int)len, (char *)in);
>>
>>              break;
>>
>>          default:
>>
>>              break;
>>
>>      }
>>
>>
>>
>>      return 0;
>>
>> }
>>
>>
>>
>> static struct libwebsocket_protocols protocols[] = {
>>
>>      {
>>
>>          "socketio-protocol",
>>
>>          callback_socketio,
>>
>>          0,
>>
>>      },
>>
>>      {
>>
>>          NULL,
>>
>>          NULL,
>>
>>          0,
>>
>>      }
>>
>> };
>>
>>
>>
>>
>>
>> int main(int argc, const char * argv[])
>>
>> {
>>
>>      struct libwebsocket_context *context;
>>
>>      struct libwebsocket *wsi_socketio;
>>
>>      int port = 80;
>>
>>      int use_ssl = 0;
>>
>>      const char *address = "echo.websocket.org";
>>
>>      //const char *address = "127.0.0.1";
>>
>>
>>
>>      int iret = 0;
>>
>>
>>
>>
>>
>>      context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL,
>>
>>                                            protocols,
>>
>>
>> libwebsocket_internal_extensions,
>>
>>                                            NULL, NULL, NULL,
>>
>>                                            -1, -1, 0, NULL);
>>
>>
>>
>>      if (context == NULL)
>>
>>      {
>>
>>          fprintf(stderr, "Create context error\n");
>>
>>          return 1;
>>
>>      }
>>
>>
>>
>>      wsi_socketio = libwebsocket_client_connect(context, address,
>> port, use_ssl, "/", address, address, protocols[0].name, -1);
>>
>>
>>
>>      if (wsi_socketio == NULL)
>>
>>      {
>>
>>          fprintf(stderr, "connect error");
>>
>>
>>
>>          return -1;
>>
>>      }
>>
>>
>>
>>      char tbuf[200] = {0};
>>
>>      char tbuf2[200] = {0};
>>
>>      int index = 0;
>>
>>
>>
>>      while (true)
>>
>>      {
>>
>>          iret = libwebsocket_service(context, 2000);
>>
>>          fprintf(stderr, "loop next %d \n", iret);
>>
>>
>>
>>          if (wsi_socketio)
>>
>>          {
>>
>>              memset(tbuf, 0, sizeof(tbuf));
>>
>>              memset(tbuf2, 0, sizeof(tbuf2));
>>
>>              snprintf(tbuf2, sizeof(tbuf2), "[test msg %d]", ++index);
>>
>>              strcpy(&tbuf[LWS_SEND_BUFFER_PRE_PADDING], tbuf2);
>>
>>              iret = libwebsocket_write(wsi_socketio,
>>
>>                                        (unsigned
>> char*)&tbuf[LWS_SEND_BUFFER_PRE_PADDING],
>>
>>
>> strlen(tbuf+LWS_SEND_BUFFER_PRE_PADDING),
>>
>>                                        LWS_WRITE_TEXT);
>>
>>              fprintf(stderr, "send msg %s, %d\n",
>> (char*)(&tbuf[LWS_SEND_BUFFER_PRE_PADDING]), iret);
>>
>>         }
>>
>>      }
>>
>>      libwebsocket_close_and_free_session(context, wsi_socketio,
>> LWS_CLOSE_STATUS_NORMAL);
>>
>>      libwebsocket_context_destroy(context);
>>
>>      // insert code here...
>>
>>      std::cout << "Hello, World!\n";
>>
>>      return 0;
>>
>> }
>> _______________________________________________
>> Libwebsockets mailing list
>> Libwebsockets at ml.libwebsockets.org
>> http://ml.libwebsockets.org/mailman/listinfo/libwebsockets
>>
>
> _______________________________________________
> Libwebsockets mailing list
> Libwebsockets at ml.libwebsockets.org
> http://ml.libwebsockets.org/mailman/listinfo/libwebsockets




More information about the Libwebsockets mailing list