源码处理流程梳理(二)

版本: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));
      }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值