Comparison

net/server_event.lua @ 5625:e67891ad18d6

net.server_event: Add support for listener.onreadtimeout(conn), which can return true to prevent the connection from being closed when a read timeout occurs
author Matthew Wild <mwild1@gmail.com>
date Fri, 24 May 2013 14:46:16 +0100
parent 5531:483f795f6f99
child 5756:61521ce49aae
comparison
equal deleted inserted replaced
5624:187f734bc996 5625:e67891ad18d6
435 end 435 end
436 return false, "setoption not implemented"; 436 return false, "setoption not implemented";
437 end 437 end
438 438
439 function interface_mt:setlistener(listener) 439 function interface_mt:setlistener(listener)
440 self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout, self.onstatus 440 self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout, self.onreadtimeout, self.onstatus
441 = listener.onconnect, listener.ondisconnect, listener.onincoming, listener.ontimeout, listener.onstatus; 441 = listener.onconnect, listener.ondisconnect, listener.onincoming,
442 end 442 listener.ontimeout, listener.onreadtimeout, listener.onstatus;
443 443 end
444
444 -- Stub handlers 445 -- Stub handlers
445 function interface_mt:onconnect() 446 function interface_mt:onconnect()
446 end 447 end
447 function interface_mt:onincoming() 448 function interface_mt:onincoming()
448 end 449 end
449 function interface_mt:ondisconnect() 450 function interface_mt:ondisconnect()
450 end 451 end
451 function interface_mt:ontimeout() 452 function interface_mt:ontimeout()
453 end
454 function interface_mt:onreadtimeout()
455 self.fatalerror = "timeout during receiving"
456 debug( "connection failed:", self.fatalerror )
457 self:_close()
458 self.eventread = nil
452 end 459 end
453 function interface_mt:ondrain() 460 function interface_mt:ondrain()
454 end 461 end
455 function interface_mt:onstatus() 462 function interface_mt:onstatus()
456 end 463 end
475 receive = client.receive; 482 receive = client.receive;
476 onconnect = listener.onconnect; -- will be called when client disconnects 483 onconnect = listener.onconnect; -- will be called when client disconnects
477 ondisconnect = listener.ondisconnect; -- will be called when client disconnects 484 ondisconnect = listener.ondisconnect; -- will be called when client disconnects
478 onincoming = listener.onincoming; -- will be called when client sends data 485 onincoming = listener.onincoming; -- will be called when client sends data
479 ontimeout = listener.ontimeout; -- called when fatal socket timeout occurs 486 ontimeout = listener.ontimeout; -- called when fatal socket timeout occurs
487 onreadtimeout = listener.onreadtimeout; -- called when socket inactivity timeout occurs
480 onstatus = listener.onstatus; -- called for status changes (e.g. of SSL/TLS) 488 onstatus = listener.onstatus; -- called for status changes (e.g. of SSL/TLS)
481 eventread = false, eventwrite = false, eventclose = false, 489 eventread = false, eventwrite = false, eventclose = false,
482 eventhandshake = false, eventstarthandshake = false; -- event handler 490 eventhandshake = false, eventstarthandshake = false; -- event handler
483 eventconnect = false, eventsession = false; -- more event handler... 491 eventconnect = false, eventsession = false; -- more event handler...
484 eventwritetimeout = false; -- even more event handler... 492 eventwritetimeout = false; -- even more event handler...
572 if interface.noreading or interface.fatalerror then -- leave this event 580 if interface.noreading or interface.fatalerror then -- leave this event
573 --vdebug( "leaving this event because:", tostring(interface.noreading or interface.fatalerror) ) 581 --vdebug( "leaving this event because:", tostring(interface.noreading or interface.fatalerror) )
574 interface.eventread = nil 582 interface.eventread = nil
575 return -1 583 return -1
576 end 584 end
577 if EV_TIMEOUT == event then -- took too long to get some data from client -> disconnect 585 if EV_TIMEOUT == event and interface:onreadtimeout() ~= true then
578 interface.fatalerror = "timeout during receiving" 586 return -1 -- took too long to get some data from client -> disconnect
579 debug( "connection failed:", interface.fatalerror ) 587 end
588 if interface._usingssl then -- handle luasec
589 if interface.eventwritetimeout then -- ok, in the past writecallback was regged
590 local ret = interface.writecallback( ) -- call it
591 --vdebug( "tried to write in readcallback, result:", tostring(ret) )
592 end
593 if interface.eventreadtimeout then
594 interface.eventreadtimeout:close( )
595 interface.eventreadtimeout = nil
596 end
597 end
598 local buffer, err, part = interface.conn:receive( interface._pattern ) -- receive buffer with "pattern"
599 --vdebug( "read data:", tostring(buffer), "error:", tostring(err), "part:", tostring(part) )
600 buffer = buffer or part
601 if buffer and #buffer > cfg.MAX_READ_LENGTH then -- check buffer length
602 interface.fatalerror = "receive buffer exceeded"
603 debug( "fatal error:", interface.fatalerror )
580 interface:_close() 604 interface:_close()
581 interface.eventread = nil 605 interface.eventread = nil
582 return -1 606 return -1
583 else -- can read 607 end
584 if interface._usingssl then -- handle luasec 608 if err and ( err ~= "timeout" and err ~= "wantread" ) then
585 if interface.eventwritetimeout then -- ok, in the past writecallback was regged 609 if "wantwrite" == err then -- need to read on write event
586 local ret = interface.writecallback( ) -- call it 610 if not interface.eventwrite then -- register new write event if needed
587 --vdebug( "tried to write in readcallback, result:", tostring(ret) ) 611 interface.eventwrite = addevent( base, interface.conn, EV_WRITE, interface.writecallback, cfg.WRITE_TIMEOUT )
588 end 612 end
589 if interface.eventreadtimeout then 613 interface.eventreadtimeout = addevent( base, nil, EV_TIMEOUT,
590 interface.eventreadtimeout:close( ) 614 function( )
591 interface.eventreadtimeout = nil 615 interface:_close()
592 end 616 end, cfg.READ_TIMEOUT
593 end 617 )
594 local buffer, err, part = interface.conn:receive( interface._pattern ) -- receive buffer with "pattern" 618 debug( "wantwrite during read attempt, reg it in writecallback but dont know what really happens next..." )
595 --vdebug( "read data:", tostring(buffer), "error:", tostring(err), "part:", tostring(part) ) 619 -- to be honest i dont know what happens next, if it is allowed to first read, the write etc...
596 buffer = buffer or part 620 else -- connection was closed or fatal error
597 if buffer and #buffer > cfg.MAX_READ_LENGTH then -- check buffer length 621 interface.fatalerror = err
598 interface.fatalerror = "receive buffer exceeded" 622 debug( "connection failed in read event:", interface.fatalerror )
599 debug( "fatal error:", interface.fatalerror )
600 interface:_close() 623 interface:_close()
601 interface.eventread = nil 624 interface.eventread = nil
602 return -1 625 return -1
603 end 626 end
604 if err and ( err ~= "timeout" and err ~= "wantread" ) then 627 else
605 if "wantwrite" == err then -- need to read on write event 628 interface.onincoming( interface, buffer, err ) -- send new data to listener
606 if not interface.eventwrite then -- register new write event if needed 629 end
607 interface.eventwrite = addevent( base, interface.conn, EV_WRITE, interface.writecallback, cfg.WRITE_TIMEOUT ) 630 if interface.noreading then
608 end 631 interface.eventread = nil;
609 interface.eventreadtimeout = addevent( base, nil, EV_TIMEOUT, 632 return -1;
610 function( ) 633 end
611 interface:_close() 634 return EV_READ, cfg.READ_TIMEOUT
612 end, cfg.READ_TIMEOUT
613 )
614 debug( "wantwrite during read attempt, reg it in writecallback but dont know what really happens next..." )
615 -- to be honest i dont know what happens next, if it is allowed to first read, the write etc...
616 else -- connection was closed or fatal error
617 interface.fatalerror = err
618 debug( "connection failed in read event:", interface.fatalerror )
619 interface:_close()
620 interface.eventread = nil
621 return -1
622 end
623 else
624 interface.onincoming( interface, buffer, err ) -- send new data to listener
625 end
626 if interface.noreading then
627 interface.eventread = nil;
628 return -1;
629 end
630 return EV_READ, cfg.READ_TIMEOUT
631 end
632 end 635 end
633 636
634 client:settimeout( 0 ) -- set non blocking 637 client:settimeout( 0 ) -- set non blocking
635 setmetatable(interface, interface_mt) 638 setmetatable(interface, interface_mt)
636 interfacelist( "add", interface ) -- add to interfacelist 639 interfacelist( "add", interface ) -- add to interfacelist