ithewei hace 4 años
padre
commit
07ae4744cb
Se han modificado 3 ficheros con 26 adiciones y 2 borrados
  1. 8 0
      event/hevent.c
  2. 2 0
      event/hloop.h
  3. 16 2
      examples/httpd/handler.cpp

+ 8 - 0
event/hevent.c

@@ -220,6 +220,14 @@ void* hio_context(hio_t* io) {
     return io->ctx;
 }
 
+size_t hio_read_bufsize(hio_t* io) {
+    return io->readbuf.len;
+}
+
+size_t hio_write_bufsize(hio_t* io) {
+    return io->write_queue_bytes;
+}
+
 haccept_cb hio_getcb_accept(hio_t* io) {
     return io->accept_cb;
 }

+ 2 - 0
event/hloop.h

@@ -255,6 +255,8 @@ HV_EXPORT void hio_set_context(hio_t* io, void* ctx);
 HV_EXPORT void* hio_context(hio_t* io);
 HV_EXPORT bool hio_is_opened(hio_t* io);
 HV_EXPORT bool hio_is_closed(hio_t* io);
+HV_EXPORT size_t hio_read_bufsize(hio_t* io);
+HV_EXPORT size_t hio_write_bufsize(hio_t* io);
 
 // set callbacks
 HV_EXPORT void hio_setcb_accept   (hio_t* io, haccept_cb  accept_cb);

+ 16 - 2
examples/httpd/handler.cpp

@@ -93,16 +93,30 @@ int Handler::largeFileHandler(const HttpContextPtr& ctx) {
         SAFE_ALLOC(buf, len);
         size_t total_readbytes = 0;
         int last_progress = 0;
+        int sendbytes_per_ms = 1024; // 1KB/ms = 1MB/s = 8Mbps
+        int sleep_ms_per_send = len / sendbytes_per_ms; // 4ms
+        int sleep_ms = sleep_ms_per_send;
         auto start_time = std::chrono::steady_clock::now();
         auto end_time = start_time;
         while (total_readbytes < filesize) {
             size_t readbytes = file.read(buf, len);
             if (readbytes <= 0) {
+                // read file error!
                 ctx->writer->close();
                 break;
             }
-            if (ctx->writer->WriteBody(buf, readbytes) < 0) {
+            int nwrite = ctx->writer->WriteBody(buf, readbytes);
+            if (nwrite < 0) {
+                // disconnected!
                 break;
+            } else if (nwrite == 0) {
+                // send too fast or peer recv too slow
+                // reduce speed of send
+                sleep_ms *= 2;
+                // size_t write_backlog = hio_write_bufsize(ctx->writer->io());
+            } else {
+                // restore speed of send
+                sleep_ms = sleep_ms_per_send;
             }
             total_readbytes += readbytes;
             int cur_progress = total_readbytes * 100 / filesize;
@@ -111,7 +125,7 @@ int Handler::largeFileHandler(const HttpContextPtr& ctx) {
                 //     ctx->request->path.c_str(), (long)total_readbytes, (long)filesize, (int)cur_progress);
                 last_progress = cur_progress;
             }
-            end_time += std::chrono::milliseconds(len / 1024); // 1KB/ms = 1MB/s = 8Mbps
+            end_time += std::chrono::milliseconds(sleep_ms);
             std::this_thread::sleep_until(end_time);
         }
         ctx->writer->End();