|
| 1 | +#include <chrono> |
| 2 | +#include <thread> |
| 3 | +#include <mongoose/mongoose.h> |
| 4 | +#include <limits.h> |
| 5 | +#include "httpServer.h" |
| 6 | +#include "libdevcore/Log.h" |
| 7 | +#include "libdevcore/Common.h" |
| 8 | +#include "ethminer-buildinfo.h" |
| 9 | + |
| 10 | +#ifndef HOST_NAME_MAX |
| 11 | +#define HOST_NAME_MAX 255 |
| 12 | +#endif |
| 13 | + |
| 14 | +using namespace dev; |
| 15 | +using namespace eth; |
| 16 | + |
| 17 | +httpServer http_server; |
| 18 | + |
| 19 | +void httpServer::tableHeader(stringstream& ss, unsigned columns) |
| 20 | +{ |
| 21 | + auto info = ethminer_get_buildinfo(); |
| 22 | + char hostName[HOST_NAME_MAX + 1]; |
| 23 | + gethostname(hostName, HOST_NAME_MAX + 1); |
| 24 | + string l = m_farm->farmLaunchedFormatted(); |
| 25 | + ss << |
| 26 | + "<head><title>" << hostName << |
| 27 | + "</title><style>tr:nth-child(even){background-color:Gainsboro;}</style>" |
| 28 | + "<meta http-equiv=refresh content=30></head><body><table width=\"50%\" border=1 cellpadding=2 cellspacing=0 align=center>" |
| 29 | + "<tr valign=top align=center style=background-color:Gold><th colspan=" << columns << ">" << info->project_version << |
| 30 | + " on " << hostName << " - " << l << "</th></tr>"; |
| 31 | +} |
| 32 | + |
| 33 | + |
| 34 | +void httpServer::getstat1(stringstream& ss) |
| 35 | +{ |
| 36 | + using namespace std::chrono; |
| 37 | + WorkingProgress p = m_farm->miningProgress(m_show_hwmonitors, m_show_power); |
| 38 | + SolutionStats s = m_farm->getSolutionStats(); |
| 39 | + tableHeader(ss, 5); |
| 40 | + ss << |
| 41 | + "<tr valign=top align=center style=background-color:Yellow>" |
| 42 | + "<th>GPU</th><th>Hash Rate (mh/s)</th><th>Temperature (C)</th><th>Fan Percent.</th><th>Power (W)</th></tr>"; |
| 43 | + double hashSum = 0.0; |
| 44 | + double powerSum = 0.0; |
| 45 | + for (unsigned i = 0; i < p.minersHashes.size(); i++) { |
| 46 | + double rate = p.minerRate(p.minersHashes[i]) / 1000000.0; |
| 47 | + hashSum += rate; |
| 48 | + ss << |
| 49 | + "<tr valign=top align=center><td>" << i << |
| 50 | + "</td><td>" << fixed << setprecision(2) << rate; |
| 51 | + if (m_show_hwmonitors && (i < p.minerMonitors.size())) { |
| 52 | + HwMonitor& hw(p.minerMonitors[i]); |
| 53 | + powerSum += hw.powerW; |
| 54 | + ss << "</td><td>" << hw.tempC << "</td><td>" << hw.fanP << "</td><td>"; |
| 55 | + if (m_show_power) |
| 56 | + ss << fixed << setprecision(0) << hw.powerW; |
| 57 | + else |
| 58 | + ss << '-'; |
| 59 | + ss << "</td></tr>"; |
| 60 | + } |
| 61 | + else |
| 62 | + ss << "</td><td>-</td><td>-</td><td>-</td></tr>"; |
| 63 | + } |
| 64 | + ss << |
| 65 | + "<tr valign=top align=center style=\"background-color:yellow\"><th>Total</th><td>" << |
| 66 | + fixed << setprecision(2) << hashSum << "</td><td colspan=2>Solutions: " << s << |
| 67 | + "</td><td>"; |
| 68 | + if (m_show_power) |
| 69 | + ss << fixed << setprecision(0) << powerSum; |
| 70 | + else |
| 71 | + ss << '-'; |
| 72 | + ss << "</td></tr></table></body></html>"; |
| 73 | +} |
| 74 | + |
| 75 | +static void ev_handler(struct mg_connection* c, int ev, void* p) |
| 76 | +{ |
| 77 | + |
| 78 | + if (ev == MG_EV_HTTP_REQUEST) { |
| 79 | + struct http_message* hm = (struct http_message*) p; |
| 80 | + if (mg_vcmp(&hm->uri, "/getstat1") && mg_vcmp(&hm->uri, "/")) |
| 81 | + mg_http_send_error(c, 404, nullptr); |
| 82 | + else { |
| 83 | + stringstream content; |
| 84 | + http_server.getstat1(content); |
| 85 | + mg_send_head(c, 200, (int)content.str().length(), "Content-Type: text/html"); |
| 86 | + mg_printf(c, "%.*s", (int)content.str().length(), content.str().c_str()); |
| 87 | + } |
| 88 | + } |
| 89 | +} |
| 90 | + |
| 91 | +void httpServer::run(unsigned short port, dev::eth::Farm* farm, bool show_hwmonitors, bool show_power) |
| 92 | +{ |
| 93 | + if (port == 0) |
| 94 | + return; |
| 95 | + m_farm = farm; |
| 96 | + m_port = to_string(port); |
| 97 | + m_show_hwmonitors = show_hwmonitors; |
| 98 | + m_show_power = show_power; |
| 99 | + new thread(bind(&httpServer::run_thread, this)); |
| 100 | +} |
| 101 | + |
| 102 | +void httpServer::run_thread() |
| 103 | +{ |
| 104 | + struct mg_mgr mgr; |
| 105 | + struct mg_connection* c; |
| 106 | + |
| 107 | + mg_mgr_init(&mgr, NULL); |
| 108 | + cnote << "Starting web server on port " << m_port; |
| 109 | + c = mg_bind(&mgr, m_port.c_str(), ev_handler); |
| 110 | + if (c == NULL) { |
| 111 | + cwarn << "Failed to create web listener"; |
| 112 | + return; |
| 113 | + } |
| 114 | + |
| 115 | + // Set up HTTP server parameters |
| 116 | + mg_set_protocol_http_websocket(c); |
| 117 | + |
| 118 | + for (;;) |
| 119 | + mg_mgr_poll(&mgr, 1000); |
| 120 | +} |
| 121 | + |
0 commit comments