1 module yu.asyncsocket.server.connection; 2 3 import yu.timer.timingwheeltimer; 4 import yu.asyncsocket.tcpsocket; 5 import yu.eventloop; 6 import yu.memory.allocator; 7 import yu.task; 8 import yu.exception; 9 10 @trusted abstract class ServerConnection : IWheelTimer!YuAlloctor { 11 this(TCPSocket socket) { 12 restSocket(socket); 13 } 14 15 ~this() { 16 if (_socket) 17 yDel(_socket); 18 } 19 20 final TCPSocket restSocket(TCPSocket socket) { 21 TCPSocket tmp = _socket; 22 if (_socket !is null) { 23 _socket.setCloseCallBack(null); 24 _socket.setReadCallBack(null); 25 _socket = null; 26 _loop = null; 27 } 28 if (socket !is null) { 29 _socket = socket; 30 _loop = socket.eventLoop; 31 _socket.setCloseCallBack(&doClose); 32 _socket.setReadCallBack(&onRead); 33 } 34 return tmp; 35 } 36 37 final bool isAlive() @trusted { 38 return _socket && _socket.isAlive; 39 } 40 41 final bool active() @trusted nothrow { 42 if (_socket is null) 43 return false; 44 bool active = false; 45 yuCathException(_socket.start(), active); 46 if (active) 47 onActive(); 48 return active; 49 } 50 51 final void write(const(ubyte)[] data, TCPWriteCallBack cback = null) @trusted { 52 if (_loop.isInLoopThread()) { 53 _postWrite(data, cback); 54 } else { 55 auto task = makeTask(yuAlloctor, &_postWrite, data, cback); 56 task.finishedCall = &_loop.finishDoFreeYuTask; 57 _loop.post(task); 58 } 59 } 60 61 final void write(TCPWriteBuffer buffer) @trusted 62 { 63 if (_loop.isInLoopThread()) { 64 _postWriteBuffer(buffer); 65 } else { 66 auto task = makeTask(yuAlloctor, &_postWriteBuffer, buffer); 67 task.finishedCall = &_loop.finishDoFreeYuTask; 68 _loop.post(task); 69 } 70 } 71 72 73 final void restTimeout() @trusted { 74 if (_loop.isInLoopThread()) { 75 rest(); 76 } else { 77 auto task = makeTask(yuAlloctor, &rest, 0); 78 task.finishedCall = &_loop.finishDoFreeYuTask; 79 _loop.post(task); 80 } 81 } 82 83 pragma(inline) final void close() @trusted { 84 _loop.post(&_postClose); 85 } 86 87 final @property tcpSocket() @safe { 88 return _socket; 89 } 90 91 final @property eventLoop() @safe { 92 return _loop; 93 } 94 95 protected: 96 void onActive() nothrow; 97 void onClose() nothrow; 98 void onRead(in ubyte[] data) nothrow; 99 100 private: 101 final void _postClose() { 102 if (_socket) 103 _socket.close(); 104 } 105 106 final void _postWriteBuffer(TCPWriteBuffer buffer) 107 { 108 if (_socket) { 109 rest(); 110 _socket.write(buffer); 111 } else 112 buffer.doFinish(); 113 } 114 115 final void _postWrite(const(ubyte)[] data, TCPWriteCallBack cback) { 116 if (_socket) { 117 rest(); 118 _socket.write(data, cback); 119 } else if (cback) 120 cback(data, 0); 121 } 122 123 final void doClose() nothrow { 124 stop(); 125 onClose(); 126 } 127 128 private: 129 TCPSocket _socket; 130 EventLoop _loop; 131 }