版本:mongoose 6.14
1.初始化
//初始化
mg_mgr_init(&mgr, NULL);
->mg_mgr_init_opt(m, user_data, opts);
->opts.num_ifaces = mg_num_ifaces;
->opts.ifaces = mg_ifaces;//MG_SOCKET_IFACE_VTABLE
#define MG_SOCKET_IFACE_VTABLE \
{ \
mg_socket_if_init, \
mg_socket_if_free, \
mg_socket_if_add_conn, \
mg_socket_if_remove_conn, \
mg_socket_if_poll, \
mg_socket_if_listen_tcp, \
mg_socket_if_listen_udp, \
mg_socket_if_connect_tcp, \
mg_socket_if_connect_udp, \
mg_socket_if_tcp_send, \
mg_socket_if_udp_send, \
mg_socket_if_tcp_recv, \
mg_socket_if_udp_recv, \
mg_socket_if_create_conn, \
mg_socket_if_destroy_conn, \
mg_socket_if_sock_set, //设置非阻塞 \
mg_socket_if_get_conn_addr, \
}
2.绑定端口
pMgc = mg_bind(&mgr, REST_SVR_LISTEN_PORT, my_handler);
->mg_bind_opt(srv, address, MG_CB(event_handler, user_data), opts)
->mg_parse_address(address, &sa, &proto, host, sizeof(host)) <= 0) //监听地址
->mg_create_connection(mgr, callback, add_sock_opts)
->mg_create_connection_base(mgr, callback, opts);
->conn->handler = callback; //设置mg_connection handler,自定义回调接口
->rc = nc->iface->vtable->listen_tcp(nc, &nc->sa); //开启TCP监听
3.设置http协议回调
//设置http协议回调接口
mg_set_protocol_http_websocket(pMgc); //设置http协议回调接口
-> nc->proto_handler = mg_http_handler;
4.信息处理流程
mg_mgr_poll(&mgr, 2000);
->m->ifaces[i]->vtable->poll(m->ifaces[i], timeout_ms);
//重要的轮询接口
1)mg_socket_if_poll
->select((int) max_fd + 1, &read_set, &write_set, &err_set, 200ms); //select
->mg_mgr_handle_conn(nc, fd_flags//1, now);
->mg_if_poll(nc, now)
->mg_call(nc, NULL, nc->user_data, MG_EV_POLL, &now_t);
->mg_accept_conn(nc);
->sock = accept(lc->sock, &sa.sa, &sa_len); //accept到请求后
->nc = mg_if_accept_new_conn(lc); //accept new conn
->mg_sock_set(nc, sock); //设置非阻塞
->mg_if_accept_tcp_cb(nc, &sa, sa_len);、
-> mg_call(nc, NULL, nc->user_data, MG_EV_ACCEPT, &nc->sa);
->ev_handler(nc, ev, ev_data MG_UD_ARG(user_data)); //调用协议处理回调 mg_http_handler()
->mg_call(nc, nc->handler, nc->user_data, ev, ev_data); //调用用户注册回调 my_handler()
->mg_if_can_recv_cb(nc); //接收数据
->mg_do_recv(nc);
->res = mg_recv_tcp(nc, buf, len)
->n = nc->iface->vtable->tcp_recv(nc, buf, len); //mg_socket_if_tcp_recv
->mg_call(nc, NULL, nc->user_data, MG_EV_RECV, &n);
->ev_handler(nc, ev, ev_data MG_UD_ARG(user_data)); //调用协议处理回调 mg_http_handler()
->mg_call(nc, nc->handler, nc->user_data, ev, ev_data); //调用用户注册回调 my_handler()
->req_len = mg_parse_http(io->buf, io->len, hm, is_req);
->trigger_ev = nc->listener ? MG_EV_HTTP_REQUEST : MG_EV_HTTP_REPLY;
->deliver_chunk(nc, hm, req_len);
->mg_http_call_endpoint_handler(nc, trigger_ev, hm); //信息已接收完,调用用户注册回调接口
->mg_call(nc, pd->endpoint_handler ? pd->endpoint_handler : nc->handler,user_data, ev, hm);
6.目前版本的http服务需要客户端执行socket关闭操作,服务端暂无自动关闭的流程,可以再协议回调接口中增加Connection:close相关信息的解析进行关闭,如下,亲测有效
/* This for Connection: close case, Server send buf data and close the socket
*/
struct mg_str* pclosed;
if ((pclosed= mg_get_http_header(hm, "Connection")) != NULL &&
mg_vcasecmp(pclosed, "close") == 0)
{
nc->flags = MG_F_SEND_AND_CLOSE;
DBG(("start close %p %s %.*s %.*s %s", nc, addr, (int) hm->method.len, hm->method.p,
(int) hm->uri.len, hm->uri.p, hm->message));
}
589

被折叠的 条评论
为什么被折叠?



