Channel.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #ifndef HV_CHANNEL_HPP_
  2. #define HV_CHANNEL_HPP_
  3. #include <string>
  4. #include <functional>
  5. #include <memory>
  6. #include "hloop.h"
  7. #include "hsocket.h"
  8. #include "Buffer.h"
  9. namespace hv {
  10. class Channel {
  11. public:
  12. Channel(hio_t* io = NULL) {
  13. io_ = io;
  14. fd_ = -1;
  15. id_ = 0;
  16. ctx_ = NULL;
  17. if (io) {
  18. fd_ = hio_fd(io);
  19. id_ = hio_id(io);
  20. hio_set_context(io, this);
  21. hio_setcb_read(io_, on_read);
  22. hio_setcb_write(io_, on_write);
  23. hio_setcb_close(io_, on_close);
  24. }
  25. }
  26. virtual ~Channel() {
  27. close();
  28. }
  29. hio_t* io() { return io_; }
  30. int fd() { return fd_; }
  31. int id() { return id_; }
  32. int error() { return hio_error(io_); }
  33. void setContext(void* ctx) {
  34. ctx_ = ctx;
  35. }
  36. void* context() {
  37. return ctx_;
  38. }
  39. bool isOpened() {
  40. if (io_ == NULL) return false;
  41. return id_ == hio_id(io_) && hio_is_opened(io_);
  42. }
  43. bool isClosed() {
  44. return !isOpened();
  45. }
  46. int startRead() {
  47. if (!isOpened()) return 0;
  48. return hio_read_start(io_);
  49. }
  50. int stopRead() {
  51. if (!isOpened()) return 0;
  52. return hio_read_stop(io_);
  53. }
  54. int write(Buffer* buf) {
  55. if (!isOpened()) return 0;
  56. return hio_write(io_, buf->data(), buf->size());
  57. }
  58. int write(const std::string& str) {
  59. if (!isOpened()) return 0;
  60. return hio_write(io_, str.data(), str.size());
  61. }
  62. int close() {
  63. if (!isOpened()) return 0;
  64. return hio_close(io_);
  65. }
  66. public:
  67. hio_t* io_;
  68. int fd_;
  69. uint32_t id_;
  70. void* ctx_;
  71. std::function<void(Buffer*)> onread;
  72. std::function<void(Buffer*)> onwrite;
  73. std::function<void()> onclose;
  74. private:
  75. static void on_read(hio_t* io, void* data, int readbytes) {
  76. Channel* channel = (Channel*)hio_context(io);
  77. if (channel && channel->onread) {
  78. Buffer buf(data, readbytes);
  79. channel->onread(&buf);
  80. }
  81. }
  82. static void on_write(hio_t* io, const void* data, int writebytes) {
  83. Channel* channel = (Channel*)hio_context(io);
  84. if (channel && channel->onwrite) {
  85. Buffer buf((void*)data, writebytes);
  86. channel->onwrite(&buf);
  87. }
  88. }
  89. static void on_close(hio_t* io) {
  90. Channel* channel = (Channel*)hio_context(io);
  91. if (channel && channel->onclose) {
  92. channel->onclose();
  93. }
  94. }
  95. };
  96. class SocketChannel : public Channel {
  97. public:
  98. enum Status {
  99. OPENED,
  100. CONNECTING,
  101. CONNECTED,
  102. DISCONNECTED,
  103. CLOSED,
  104. } status;
  105. SocketChannel(hio_t* io) : Channel(io) {
  106. status = isOpened() ? OPENED : CLOSED;
  107. }
  108. virtual ~SocketChannel() {}
  109. bool isConnected() {
  110. return isOpened() && status == CONNECTED;
  111. }
  112. std::string localaddr() {
  113. struct sockaddr* addr = hio_localaddr(io_);
  114. char buf[SOCKADDR_STRLEN] = {0};
  115. return SOCKADDR_STR(addr, buf);
  116. }
  117. std::string peeraddr() {
  118. struct sockaddr* addr = hio_peeraddr(io_);
  119. char buf[SOCKADDR_STRLEN] = {0};
  120. return SOCKADDR_STR(addr, buf);
  121. }
  122. int send(const std::string& str) {
  123. return write(str);
  124. }
  125. };
  126. typedef std::shared_ptr<Channel> ChannelPtr;
  127. typedef std::shared_ptr<SocketChannel> SocketChannelPtr;
  128. }
  129. #endif // HV_CHANNEL_HPP_