Closed fusionJose closed 5 years ago
Disabling permessage-deflate / setting ctxCreationInfo.extensions = NULL fixes it?
No, it continues without receiving the response.
I get the code, and adapted to my aplication from here: https://gist.github.com/iUltimateLP/17604e35f0d7a859c7a263075581f99a
adapted to my aplication from here
I'm not responsible for someone else's code... I'm not really responsible for my own under a FOSS license but at least I share an interest in keeping it working all things equal.
What I suggest you do is try the provided minimal examples related to ws client operation, eg,
https://libwebsockets.org/git/libwebsockets/tree/minimal-examples/ws-client/minimal-ws-client-rx
should immediately receive ws data from libwebsockets.org.
Hi, I've tried with the minimal-ws-client-rx example. I included a writing when I get the LWS_CALLBACK_CLIENT_ESTABLISHED event previous to receive the response from server. But keep whithout receiving any data. It transmits the message but stops the program with no data received. I also deleted the use of SSL.
Here is the code:
`/*
static int interrupted, rx_seen, test; static struct lws *client_wsi;
static int callback_dumb_increment(struct lws wsi, enum lws_callback_reasons reason, void user, void *in, size_t len) { // The message we send back to the echo server const char msg[128] = "Simple webserver echo test!";
// The buffer holding the data to send
// NOTICE: data which is sent always needs to have a certain amount of memory (LWS_PRE) preserved for headers
unsigned char buf[LWS_PRE + 128];
// Allocating the memory for the buffer, and copying the message to it
memset(&buf[LWS_PRE], 0, 128);
strncpy((char*)buf + LWS_PRE, msg, 128);
int n;
json_object *jarray = json_object_new_array();
json_object *jobj_type = json_object_new_object();
json_object *jobj_ID = json_object_new_object();
json_object *jobj_action = json_object_new_object();
json_object *jobj = json_object_new_object();
jobj_type = json_object_new_int(2); /* A call from client to server */
jobj_ID = json_object_new_string("1946577");
jobj_action = json_object_new_string("BootNotification");
char *str = "{\
\"chargePointVendor\": \"MilHouse\", \
\"chargePointModel\": \"Fusion\", \
}";
//printf("str:\n---\n%s\n---\n\n", str);
json_object_array_add(jarray,jobj_type);
json_object_array_add(jarray,jobj_ID);
json_object_array_add(jarray,jobj_action);
jobj = json_tokener_parse(str);
json_object_array_add(jarray,jobj);
switch (reason) {
/* because we are protocols[0] ... */
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
lwsl_err("CLIENT_CONNECTION_ERROR: %s\n",
in ? (char *)in : "(null)");
client_wsi = NULL;
break;
case LWS_CALLBACK_CLIENT_ESTABLISHED:
lwsl_user("%s: established\n", __func__);
lws_callback_on_writable(wsi);
break;
case LWS_CALLBACK_CLIENT_WRITEABLE:
printf("[Test Protocol] The client is able to write.\n");
printf("[Test Protocol] Writing \"%s\" to server.\n", msg);
// Write the buffer from the LWS_PRE index + 128 (the buffer size)
char ping[LWS_PRE + 250];
int m;
printf("jobj from str:\n---\n%s\n---\n", json_object_to_json_string_ext(jarray, JSON_C_TO_STRING_PLAIN));
n = 0;
n = lws_snprintf((char *)ping + LWS_PRE, 250,
json_object_to_json_string_ext(jarray, JSON_C_TO_STRING_PLAIN));
//sprintf((char *)ping + LWS_PRE, json_object_to_json_string_ext(jarray, JSON_C_TO_STRING_PLAIN));
lwsl_user("Sending PING %d...\n", n);
m = lws_write(wsi, ping + LWS_PRE, n, LWS_WRITE_TEXT);
if (m < n) {
lwsl_err("sending ping failed: %d\n", m);
}
break;
case LWS_CALLBACK_CLIENT_RECEIVE:
lwsl_user("RX: %s\n", (const char *)in);
rx_seen++;
if (test && rx_seen == 10)
interrupted = 1;
break;
case LWS_CALLBACK_CLIENT_CLOSED:
client_wsi = NULL;
break;
default:
break;
}
return lws_callback_http_dummy(wsi, reason, user, in, len);
}
static const struct lws_protocols protocols[] = { { "ocpp1.6", callback_dumb_increment, 0, 0, }, { NULL, NULL, 0, 0 } };
static void sigint_handler(int sig) { interrupted = 1; }
int main(int argc, const char *argv) { struct lws_context_creation_info info; struct lws_client_connect_info i; struct lws_context context; const char p; int n = 0, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE / for LLL_ verbosity above NOTICE to be built into lws, lws
instead of =RELEASE / / | LLL_INFO / / | LLL_PARSER / / | LLL_HEADER / / | LLL_EXT / / | LLL_CLIENT / / | LLL_LATENCY / / | LLL_DEBUG */;
char inputURL[300] = "ws://192.168.12.110:8080/steve/websocket/CentralSystemService/Test1234";
int inputPort = 80;
const char *urlProtocol, *urlTempPath; // the protocol of the URL, and a temporary pointer to the path
char urlPath[300]; // The final path string
signal(SIGINT, sigint_handler);
if ((p = lws_cmdline_option(argc, argv, "-d")))
logs = atoi(p);
test = !!lws_cmdline_option(argc, argv, "-t");
lws_set_log_level(logs, NULL);
lwsl_user("LWS minimal ws client rx [-d <logs>] [--h2] [-t (test)]\n");
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
info.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */
info.protocols = protocols;
/*
* OpenSSL uses the system trust store. mbedTLS has to be told which
* CA to trust explicitly.
*/
info.client_ssl_ca_filepath = "./libwebsockets.org.cer";
/*
* since we know this lws context is only ever going to be used with
* one client wsis / fds / sockets at a time, let lws know it doesn't
* have to use the default allocations for fd tables up to ulimit -n.
* It will just allocate for 1 internal and 1 (+ 1 http2 nwsi) that we
* will use.
*/
info.fd_limit_per_thread = 1 + 1 + 1;
context = lws_create_context(&info);
if (!context) {
lwsl_err("lws init failed\n");
return 1;
}
memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */
if (lws_parse_uri(inputURL, &urlProtocol, &i.address, &i.port, &urlTempPath))
{
printf("Couldn't parse URL\n");
}
// Fix up the urlPath by adding a / at the beginning, copy the temp path, and add a \0 at the end
urlPath[0] = '/';
strncpy(urlPath + 1, urlTempPath, sizeof(urlPath) - 2);
urlPath[sizeof(urlPath) - 1] = '\0';
i.path = urlPath; // Set the info's path to the fixed up url path
i.context = context;
i.host = i.address;
i.origin = i.address;
// i.ssl_connection = LCCSCF_USE_SSL; i.ssl_connection = 0; // Don't use SSL for this test i.protocol = protocols[0].name; / "dumb-increment-protocol" / i.pwsi = &client_wsi;
if (lws_cmdline_option(argc, argv, "--h2"))
i.alpn = "h2";
lws_client_connect_via_info(&i);
while (n >= 0 && client_wsi && !interrupted)
n = lws_service(context, 1000);
lws_context_destroy(context);
lwsl_user("Completed %s\n", rx_seen > 10 ? "OK" : "Failed");
return rx_seen > 10;
}`
Thanks for your support
.. mmm I don't really care about your project. So if something is wrong there, I don't want to stop the other things I am supposed to be doing to look into it.
I do care about my project. So please don't paste changed code, just tell me does the unchanged minimal example I pointed to connect to libwebsockets.org and get RX?
Yes, your unchanged minimal example receives data. I understand you, but the only thing i would want to know is the way to transmit a message before get RX. I´m not sure I am doing this well. I fell like the socket transmits de message and closes the socket, forgetting to listen to incoming data.
Yes, your unchanged minimal example receives data.
OK, so I think there's no general problem about ws rx in lws as it is.
the only thing i would want to know is the way to transmit a message before get RX.
When the connection is ESTABLISHED, ask for a callback_on_writable(). In the WRITEABLE callback, do the lws_write() you want to do. If you want to do more, ask for a callback_on_writable() again.
I fell like the socket transmits de message and closes the socket, forgetting to listen to incoming data.
I don't know what side we're talking about but that's a decision for the code on that side when to close the ws connection. If something is wrong with what was transmitted to it, in terms of violating ws protocol, it might decide it should hang up... you should look at the logs and see what's happening there. If it;s just racing the other side, that's something you need to fix in your code.
Hi,
I have made a simple test lws client project to connect a websocket client with a server and exchange some data. Connecting to the websocket server works, sending a message to that server works too. When it comes to receiving message from websocket server, i cannot receive LWS_CALLBACK_CLIENT_RECEIVE event. I could verify that the server is sending back the response to my client. The messages are in JSON format and here are both messages, discovered by other aplication:
[2,"192339","BootNotification",{"chargePointVendor":"MilHouse","chargePointModel":"Fusion"}] [3,"192339",{"status":"Accepted","currentTime":"2019-06-20T13:50:47.651Z","interval":14400}]
And here is my code:
`#include
include
include
include
include
include
static int bExit; static int bDenyDeflate = 1;
static int callback_test(struct lws wsi, enum lws_callback_reasons reason, void user, void* in, size_t len);
static int zero_length_ping = 0;
// Escape the loop when a SIGINT signal is received static void onSigInt(int sig) { bExit = 1; }
// The registered protocols static struct lws_protocols protocols[] = { { "ocpp1.6", // Protocol name callback_test, // Protocol callback 0, // Data size per session (can be left empty) 512, // Receive buffer size (can be left empty)
};
// The extensions LWS supports, without them some requests may not be able to work static const struct lws_extension extensions[] = { { "permessage-deflate", lws_extension_callback_pm_deflate, "permessage-deflate; client_max_window_bits" }, { "deflate-frame", lws_extension_callback_pm_deflate, "deflate_frame" }, { NULL, NULL, NULL } // Always needed at the end };
// List to identify the indices of the protocols by name enum protocolList { PROTOCOL_TEST,
};
// Callback for the test protocol static int callback_test(struct lws wsi, enum lws_callback_reasons reason, void user, void* in, size_t len) { // The message we send back to the echo server const char msg[128] = "Simple webserver echo test!";
}
// Main application entry int main() { lws_set_log_level(LLL_ERR | LLL_WARN, lwsl_emit_syslog); // We don't need to see the notice messages
}`