processing is completed and the allocation released after ESTABLISHED or the
HTTP callback, even with a pool of 1 many connections can be handled rapidly.
+2) There is a new callback that allows the user code to get acccess to the
+optional close code + aux data that may have been sent by the peer.
+
+LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
+ The peer has sent an unsolicited Close WS packet. @in and
+ @len are the optional close code (first 2 bytes, network
+ order) and the optional additional information which is not
+ defined in the standard, and may be a string or non-human-
+ readble data.
+ If you return 0 lws will echo the close and then close the
+ connection. If you return nonzero lws will just close the connection.
+
+As usual not handling it does the right thing, if you're not interested in it
+just ignore it.
+
+The test server has "open and close" testing buttons at the bottom, if you
+open and close that connection, on close it will send a close code 3000 decimal
+and the string "Bye!" as the aux data.
+
+The test server dumb-increment callback handles this callback reason and prints
+
+lwsts[15714]: LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: len 6
+lwsts[15714]: 0: 0x0B
+lwsts[15714]: 1: 0xB8
+lwsts[15714]: 2: 0x42
+lwsts[15714]: 3: 0x79
+lwsts[15714]: 4: 0x65
+lwsts[15714]: 5: 0x21
+
User api changes
----------------
LWS_CALLBACK_UNLOCK_POLL = 36,
LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY = 37,
+ LWS_CALLBACK_WS_PEER_INITIATED_CLOSE = 38,
/****** add new things just above ---^ ******/
* len == 1 allows external threads to be synchronized against
* wsi lifecycle changes if it acquires the same lock for the
* duration of wsi dereference from the other thread context.
+ *
+ * LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
+ * The peer has sent an unsolicited Close WS packet. @in and
+ * @len are the optional close code (first 2 bytes, network
+ * order) and the optional additional information which is not
+ * defined in the standard, and may be a string or non-human-
+ * readble data.
+ * If you return 0 lws will echo the close and then close the
+ * connection. If you return nonzero lws will just close the
+ * connection.
*/
LWS_VISIBLE LWS_EXTERN int
callback(const struct lws *wsi, enum lws_callback_reasons reason, void *user,
switch (wsi->u.ws.opcode) {
case LWSWSOPC_CLOSE:
+
/* is this an acknowledgement of our close? */
if (wsi->state == LWSS_AWAITING_CLOSE_ACK) {
/*
/* if he sends us 2 CLOSE, kill him */
return -1;
+ if (user_callback_handle_rxflow(
+ wsi->protocol->callback, wsi,
+ LWS_CALLBACK_WS_PEER_INITIATED_CLOSE,
+ wsi->user_space,
+ &wsi->u.ws.rx_user_buffer[
+ LWS_SEND_BUFFER_PRE_PADDING],
+ wsi->u.ws.rx_user_buffer_head))
+ return -1;
+
lwsl_parser("server sees client close packet\n");
wsi->state = LWSS_RETURNED_CLOSE_ALREADY;
/* deal with the close packet contents as a PONG */
n = LWS_CALLBACK_HTTP_WRITEABLE;
break;
}
- lwsl_info("%s: %p (user=%p)\n", __func__, wsi, wsi->user_space);
+ lwsl_debug("%s: %p (user=%p)\n", __func__, wsi, wsi->user_space);
return user_callback_handle_rxflow(wsi->protocol->callback,
wsi, (enum lws_callback_reasons) n,
wsi->user_space, NULL, 0);
/* you could return non-zero here and kill the connection */
break;
+ /*
+ * this just demonstrates how to handle
+ * LWS_CALLBACK_WS_PEER_INITIATED_CLOSE and extract the peer's close
+ * code and auxiliary data. You can just not handle it if you don't
+ * have a use for this.
+ */
+ case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
+ lwsl_notice("LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: len %d\n",
+ len);
+ for (n = 0; n < (int)len; n++)
+ lwsl_notice(" %d: 0x%02X\n", n,
+ ((unsigned char *)in)[n]);
+ break;
+
default:
break;
}
}
function ot_close() {
- socket_ot.close();
+ socket_ot.close(3000, "Bye!");
}
/* lws-mirror protocol */