goahead源码解析(四)---------websListen()与websServiceEvents()函数

前面有一个websListen()的函数,作用是监听端口,并且绑定回调函数。
它将创建好的套接字以WebsSocket结构体的形式添加到socketList中,并且设置handleMask为SOCKET_READABLE。绑定的回调函数是websAccept()。
websAccept是创建一个套接字,并注册一个读事件。然后进入socketEvent()函数的事件处理流程。

readEvents

在这里插入图片描述
在这里插入图片描述

websServiceEvents()

websServiceEvents(&finished);

这个finished我前面(二)中已经提到过,初始值是0,在程序终止后会变为1.

/*
    Basic event loop. SocketReady returns true when a socket is ready for service. SocketSelect will block until an
    event occurs. SocketProcess will actually do the servicing.
 */
PUBLIC void websServiceEvents(int *finished)
{
    int     delay, nextEvent;

    if (finished) {
        *finished = 0;
    }
    delay = 0;
    while (!finished || !*finished) {
        if (socketSelect(-1, delay)) {
            socketProcess();
        }
#if ME_GOAHEAD_CGI
        delay = websCgiPoll();
#else
        delay = MAXINT;
#endif
        nextEvent = websRunEvents();
        delay = min(delay, nextEvent);
    }
}

根据函数前的注释,该函数是基础的事件循环。正常情况下会阻塞在socketSelect(),只有当事件发生时,才会执行socketProcess.
我们来看它的实现逻辑:
先将finish值置为0。
进入while循环,执行socketSelect函数

socketSelect函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
重点在于这个select函数。
该函数声明如下
int select(int nfds, fd_set* readset, fd_set* writeset, fe_set* exceptset, struct timeval* timeout);
参数:

   nfds           需要检查的文件描述字个数
   readset     用来检查可读性的一组文件描述字。
   writeset     用来检查可写性的一组文件描述字。
   exceptset  用来检查是否有异常条件出现的文件描述字。(注:错误不包括在异常条件之内)
   timeout      超时,填NULL为阻塞,填0为非阻塞,其他为一段超时时间

返回值:

   返回fd的总数,错误时返回SOCKET_ERROR

因此socketSelect函数主要作用就是阻塞,等到发生读写或者异常事件。
在这里插入图片描述
上面读事件的处理就是socketAccept函数。将捕获到的事件发生的socket传入socketAccept,在socketAccept内执行回调,回调函数是websAccept,也就是上面最开始讲的函数。
当程序终止时,finished变为1,跳出while循环。

流程示例

当网页调用action,像服务端发送请求时,
服务端的MAIN函数中的websServiceEvents中的socketSelect函数中的select函数通过轮询,捕获到了这个请求。然后socketAccept创建结构体保存了收到的所有消息内容,之后调用readEvents将收到的消息通过websPump函数,对照route.txt中写的规则,找到处理该请求所需的程序。

route uri=/action handler=action

即处理action,需要的是actionHandle。
而actionHandle正如我在前面(三)中讲过的,就是将用户定义的action及其处理函数添加到哈希表中。通过查找对应action名称,执行对应的函数。
然后再处理函数中,向web返回数据。例如

    websSetStatus(wp, 200);
    websWriteHeaders(wp, -1, 0);
    websWriteEndHeaders(wp);
    websFlush(wp, 0);
    websDone(wp);

结束。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值