网络问题排查实战经典案例汇总( 五 )

* client to hold on to an idle HTTP/1.1 connection* @log_filepath: VHOST: filepath to append logs to... this is opened before* any dropping of initial privileges* @mounts: VHOST: optional linked list of mounts for this vhost* @server_string: CONTEXT: string used in HTTP headers to identify server* software, if , "libwebsockets".struct lws_context_creation_info {int port; /* VH */const char *iface; /* VH */const struct lws_protocols *protocols; /* VH */const struct lws_extension *extensions; /* VH */const struct lws_token_limits *token_limits; /* context */const char *ssl_private_key_password; /* VH */const char *ssl_cert_filepath; /* VH */const char *ssl_private_key_filepath; /* VH */const char *ssl_ca_filepath; /* VH */const char *ssl_cipher_list; /* VH */const char *http_proxy_address; /* VH */unsigned int http_proxy_port; /* VH */int gid; /* context */int uid; /* context */unsigned int options; /* VH + context */void *user; /* context */int ka_time; /* context */int ka_probes; /* context */int ka_interval; /* context */#ifdef LWS_OPENSSL_SUPPORTSSL_CTX *provided_client_ssl_ctx; /* context */#else /* maintain structure layout either way */void *provided_client_ssl_ctx;#endifshort max_http_header_data; /* context */short max_http_header_pool; /* context */unsigned int count_threads; /* context */unsigned int fd_limit_per_thread; /* context */unsigned int timeout_secs; /* VH */const char *ecdh_curve; /* VH */const char *vhost_name; /* VH */const char * const *plugin_dirs; /* context */const struct lws_protocol_vhost_options *pvo; /* VH */int keepalive_timeout; /* VH */const char *log_filepath; /* VH */const struct lws_http_mount *mounts; /* VH */const char *server_string; /* context *//* Add new things just above here ---^* This is part of the ABI, don't needlessly break compatibility* The below is to ensure later library versions with new* members added above will see 0 (default) even if the app* was not built against the newer headers.void *_unused[8];
上述结构体中的ka_time、ka_interval和ka_probes三个字段 , 是心跳参数 , 这三个参数的含义是:
 

ka_time:两个心跳包之间的时间间隔; ka_interval:给对端发送心跳包之后 , 收不到对端ACK确认超时时间; ka_probes:心跳包探测次数 。
 
我们在调用lws_create_context接口初始化libwebsockets库时 , 可以指定这三个参数
static lws_context* CreateContext{lws_set_log_level( 0xFF, );lws_context* plcContext = ;lws_context_creation_info tCreateinfo;memset(&tCreateinfo, 0, sizeof tCreateinfo);tCreateinfo.port = CONTEXT_PORT_NO_LISTEN;tCreateinfo.protocols = protocols;tCreateinfo.ka_time = 10; // 心跳包间的时间间隔tCreateinfo.ka_interval = 10; // 发出心跳包后没有收到ACK确认包时重发心跳包的超时时间tCreateinfo.ka_probes = 3; // 心跳探测次数 , 对于windows操作系统 , 此设置是无效的 , Windows系统时固定为10次 , 不可修改tCreateinfo.options = LWS_SERVER_OPTION_DISABLE_IPV6;plcContext = lws_create_context(&tCreateinfo);return plcContext;}
跟进libwebsockets库的开源代码中 , 函数lws_create_context的内部 , 最终调用的是lws_plat_set_socket_options接口 , 该接口内部最终是给对应的socket套接字设置心跳参数的 , 如下:
LWS_VISIBLE intlws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd){int optval = 1;int optlen = sizeof(optval);u_long optl = 1;DWORD dwBytesRet;struct tcp_keepalive alive;int protonbr;#ifndef _WIN32_WCEstruct protoent *tcp_proto;#endifif (vhost->ka_time) {/* enable keepalive on this socket */// 先调用setsockopt打开发送心跳包(设置)选项optval = 1;if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,(const char *)&optval, optlen) < 0)return 1;


推荐阅读