Issue #36 on hold
Junt Van
created an issue

http://www.wangafu.net/~nickm/libevent-book/Ref6_bufferevent.html says that flush method is available

int bufferevent_flush(struct bufferevent *bufev,
    short iotype, enum bufferevent_flush_mode state);

but I can not find appropriate method...

My problem is: I'm closing socket by timeout, and sent data before close, but output buffer is not flushed before socket closed

object(EventBuffer)#30 (2) {
["length"]=>  int(18)
["contiguous_space"]=> int(18)                                                                                                              
}      

so client receive nothing...

I've tried different combination of available method before socket close, but nothing helps. Can you recommended me correct way to flush output buffer before close?

        if($bev instanceof \EventBufferEvent){
            $bev->write($response); 
             var_dump($bev->output);
            $bev->close();
        }

Comments (10)

  1. Junt Van reporter
    • edited description

    Found in examples exactly the same, that I need but for other protocol at pecl-event / examples / sslfilter.php

    case strncmp('QUIT', $line, 4):
                    $this->ev_write($id, "250 OK quit\r\n");
                    $this->ev_close($id);
                    break;
    
  2. Ruslan Osmanov repo owner

    As far as I can see, bufferevent_flush() currently does nothing for socket-based bufferevents:

    Currently (as of Libevent 2.0.5-beta), bufferevent_flush() is only implemented for some bufferevent types. In particular, socket-based bufferevents don’t have it.

    Try to call fflush(), if your bufferevent is based on PHP's resource.

  3. Junt Van reporter

    I'm creating connection using

      if (!empty($context) and $context instanceof \EventSslContext) {
                $bev = \EventBufferEvent::sslSocket($this->event_base, $fd, $context, \EventBufferEvent::SSL_ACCEPTING, \EventBufferEvent::OPT_CLOSE_ON_FREE);
            } else {
                $bev = new \EventBufferEvent($this->event_base, $fd, \EventBufferEvent::OPT_CLOSE_ON_FREE | \EventBufferEvent::OPT_DEFER_CALLBACKS);
            }
    

    tried to reach "row" socket, but did not find a way to reach it, $fd in every object is just int. Any other ideas how to do it using libevent?

  4. Ruslan Osmanov repo owner

    You can flush bufferevent by freeing it. The \EventBufferEvent::OPT_CLOSE_ON_FREE option may not help due to PHP's reference counting, if you do not destroy the EventBufferEvent explicitly. So if you don't need the bufferevent and want to flush it, you can explicitly destroy and free the object by assigning null:

    <?php
    $bev->free();
    // free() may be not enough, if you have references to this object.
    $bev = null;
    
  5. Fred Brown

    Junt Van, you mention timeout, I could be misunderstanding, but if a connection has timeout then you should consider it broken. You cannot flush a broken connection. If EventBufferEvent could send the data it would do so without any intervention.

  6. Log in to comment