diff --git a/das-dn/CMakeLists.txt b/das-dn/CMakeLists.txt index 88cc8cca..3e73fbb9 100644 --- a/das-dn/CMakeLists.txt +++ b/das-dn/CMakeLists.txt @@ -61,7 +61,9 @@ include_directories ( inc/uuid inc/sqlite inc/nopoll + inc/websockets inc/crypto + cmg/ inc/mqtt) set (APP_SRCS @@ -136,24 +138,31 @@ set (APP_SRCS ${APP_SRCS} if (USE_WEBSOCKET) set (APP_SRCS ${APP_SRCS} - third_party/nopoll/nopoll.c - third_party/nopoll/nopoll_conn.c - third_party/nopoll/nopoll_conn_opts.c - third_party/nopoll/nopoll_listener.c - third_party/nopoll/nopoll_ctx.c - third_party/nopoll/nopoll_decl.c - third_party/nopoll/nopoll_io.c - third_party/nopoll/nopoll_log.c - third_party/nopoll/nopoll_msg.c) + third_party/websockets/easywsclient.cpp + ) +# find_package(websockets) +# set (APP_LIBS ${APP_LIBS} websockets) + +# set (APP_SRCS ${APP_SRCS} +# third_party/nopoll/nopoll.c +# third_party/nopoll/nopoll_conn.c +# third_party/nopoll/nopoll_conn_opts.c +# third_party/nopoll/nopoll_listener.c +# third_party/nopoll/nopoll_ctx.c +# third_party/nopoll/nopoll_decl.c +# third_party/nopoll/nopoll_io.c +# third_party/nopoll/nopoll_log.c +# third_party/nopoll/nopoll_msg.c) set (APP_LIBS ${APP_LIBS} ssl crypto) - add_definitions(-DUSE_WEBSOCKET) - add_definitions(-DNOPOLL_OS_UNIX=1) - add_definitions(-DSHOW_DEBUG_LOG) - add_definitions(-DNOPOLL_HAVE_VASPRINTF=1) - add_definitions(-DNOPOLL_HAVE_TLSv10_ENABLED=1) - add_definitions(-DNOPOLL_HAVE_TLSv11_ENABLED=1) - add_definitions(-DNOPOLL_HAVE_TLSv12_ENABLED=1) - add_definitions(-DNOPOLL_HAVE_TLS_FLEXIBLE_ENABLED=1) +# add_definitions(-DUSE_WEBSOCKET) +# add_definitions(-DNOPOLL_OS_UNIX=1) +# add_definitions(-DSHOW_DEBUG_LOG) +# add_definitions(-DNOPOLL_HAVE_VASPRINTF=1) +# add_definitions(-DNOPOLL_HAVE_TLSv10_ENABLED=1) +# add_definitions(-DNOPOLL_HAVE_TLSv11_ENABLED=1) +# add_definitions(-DNOPOLL_HAVE_TLSv12_ENABLED=1) +# add_definitions(-DNOPOLL_HAVE_TLS_FLEXIBLE_ENABLED=1) + endif () if (USE_MQTT) diff --git a/das-dn/cmg/main.cpp b/das-dn/cmg/main.cpp index 68561c61..a53a250c 100644 --- a/das-dn/cmg/main.cpp +++ b/das-dn/cmg/main.cpp @@ -186,6 +186,7 @@ int main(int argc, char** argv) signal(SIGFPE, stop); CRYDevice ryDevice; + g_conn = &ryDevice; do { vLog(LOG_DEBUG, "system initialize...\n"); diff --git a/das-dn/cmg/ry.cpp b/das-dn/cmg/ry.cpp index 49da4ad6..7a419650 100644 --- a/das-dn/cmg/ry.cpp +++ b/das-dn/cmg/ry.cpp @@ -1,17 +1,25 @@ #include "ry.h" #include + CRYDevice::CRYDevice() { +#if 1 +#else ctx = NULL; conn = NULL; - msg_count = 0; +#endif + + pthread_mutex_init(&m_SendQueueMutex, NULL); + pthread_mutex_init(&m_RecvQueueMutex, NULL); } CRYDevice::~CRYDevice() { - +// client.setEnd(true); + pthread_mutex_destroy(&m_SendQueueMutex); + pthread_mutex_destroy(&m_RecvQueueMutex); } bool CRYDevice::configInitializeMemory(void) @@ -249,7 +257,8 @@ bool CRYDevice::configWriteDatabaseCFG(void) } return false; } - +#if 1 +#else BOOLEAN CRYDevice::websocket_msg_join(noPollMsg **msg, int msg_count, BYTE* &buffer, int &buffer_size) { if (msg_count <= 0 || msg_count >= MAX_MSG_COUNT) return FALSE; @@ -280,7 +289,7 @@ int CRYDevice::websocket_write(const char * buffer, int buffer_len) result = nopoll_conn_flush_writes(conn, 2000000, result); return (result == buffer_len) ? 0 : -1; } - +#endif bool CRYDevice::publish_sensor_data(const std::string traceId, const char* command, const Json::Value payload) { Json::StreamWriterBuilder builder; @@ -305,6 +314,7 @@ bool CRYDevice::publish_sensor_data(const std::string traceId, const char* comma jsonRoot["data"] = payload; std::string outputConfig = Json::writeString(builder, jsonRoot); + if (traceId != "") { vLog(LOG_DEBUG, "send cmd: %s, payload: %d\n", command, outputConfig.length()); @@ -314,13 +324,18 @@ bool CRYDevice::publish_sensor_data(const std::string traceId, const char* comma vLog(LOG_DEBUG, "send cmd: %s, payload: %d\n", command, outputConfig.length()); } } +#if 1 + //vLog(LOG_DEBUG, "push a frame <%s>\n", command); + sendMsg(outputConfig); + //g_conn->send(outputConfig); +#else int rc = websocket_write(outputConfig.c_str(), outputConfig.length()); if (rc != 0) { vLog(LOG_DEBUG, "websocket write is error<%d>,insert into database.\n", rc); //插入数据库 return false; } - +#endif return true; } @@ -3102,10 +3117,6 @@ BOOLEAN CRYDevice::ry_init(const char *host, const int port, const char *nodeId, snprintf(m_version, sizeof(m_version), "%s", version); m_port = port; - ctx = nopoll_ctx_new(); - nopoll_log_enable(ctx, nopoll_false); - nopoll_log_color_enable(ctx, nopoll_false); - status = 2; //0 - 离线, 1 - 在线, 2 - 未配置 m_dataAcquisitionReload = false; @@ -3148,7 +3159,26 @@ BOOLEAN CRYDevice::ry_init(const char *host, const int port, const char *nodeId, } } status = 1; - +#if 1 +#if 0 + char url[512]; + snprintf(url, sizeof(url), "ws://%s:%d/node/%s/%s", m_host, m_port, m_nodeId, m_version); + client.init(url); + client.set_ssl(NULL, NULL, NULL, 0); + client.create(); + client.connect(0); + client.run(200); + g_conn = &client; +#else + char url[520]; + snprintf(url, sizeof(url), "ws://%s:%d/node/%s/%s", m_host, m_port, m_nodeId, m_version); + m_ws = WebSocket::from_url(url); + last_connect_sec = system32.timers; +#endif +#else + ctx = nopoll_ctx_new(); + nopoll_log_enable(ctx, nopoll_false); + nopoll_log_color_enable(ctx, nopoll_false); if (ctx != NULL) { nopoll_conn_connect_timeout(ctx, 50000); char url[512]; @@ -3160,12 +3190,103 @@ BOOLEAN CRYDevice::ry_init(const char *host, const int port, const char *nodeId, conn = nopoll_conn_new(ctx, m_host, cPort, NULL, url, NULL, NULL); g_conn = conn; } - +#endif return TRUE; } +int CRYDevice::sendMsg(std::string sMessage) +{ + if (NULL != m_ws && m_ws->getReadyState() == easywsclient::WebSocket::OPEN) + { + pthread_mutex_lock(&m_SendQueueMutex); + m_SendQueue.push(sMessage); + pthread_mutex_unlock(&m_SendQueueMutex); + + return (int)sMessage.length(); + } + return 0; +} + +int CRYDevice::recvMsg(std::string sMessage) +{ + pthread_mutex_lock(&m_RecvQueueMutex); + m_recvMsgQueue.push(sMessage); + pthread_mutex_unlock(&m_RecvQueueMutex); + + return (int)sMessage.length(); +} + bool CRYDevice::ry_run(void) { +#if 1 +#if 0 + std::string msg; + do { + msg = client.getRecvMsg(); + if (msg != "") + { + on_message((const char *)msg.c_str(), msg.length()); + } + client.popRecvMsg(); + } while (msg != ""); +#else + if (m_ws != NULL) + { + if (m_ws->getReadyState() != WebSocket::CLOSED) + { + CRYDevice *rydevice = this; + std::string data; + m_ws->poll(); + m_ws->dispatch([rydevice](const std::string & message) { + //printf(">>> %s\n", message.c_str()); + rydevice->on_message((const char *)message.c_str(), message.length()); + }); + //如果有数据待发 + if (!m_SendQueue.empty()) + { + std::string sMessage; + while (1) + { + pthread_mutex_lock(&m_SendQueueMutex); + if (!m_SendQueue.empty()) + { + sMessage = m_SendQueue.front(); + m_SendQueue.pop(); + } + else + { + pthread_mutex_unlock(&m_SendQueueMutex); + break; + } + pthread_mutex_unlock(&m_SendQueueMutex); + m_ws->send(sMessage); + } + } + } + else if (m_ws->getReadyState() == WebSocket::CLOSED) + { + delete m_ws; + m_ws = NULL; + char url[520]; + snprintf(url, sizeof(url), "ws://%s:%d/node/%s/%s", m_host, m_port, m_nodeId, m_version); + m_ws = WebSocket::from_url(url); + last_connect_sec = system32.timers; + vLog(LOG_DEBUG, "here reconnect.\n"); + } + } + else + { + if (last_connect_sec > 0 && system32.timers > (last_connect_sec + 8)) { + char url[520]; + snprintf(url, sizeof(url), "ws://%s:%d/node/%s/%s", m_host, m_port, m_nodeId, m_version); + m_ws = WebSocket::from_url(url); + last_connect_sec = system32.timers; + vLog(LOG_DEBUG, "here reconnect.\n"); + } + } + +#endif +#else nopoll_bool isOk = nopoll_conn_is_ready(conn); if (isOk) { last_connect_sec = system32.timers; @@ -3211,6 +3332,7 @@ bool CRYDevice::ry_run(void) last_connect_sec = system32.timers; } } +#endif BOOLEAN sec_changed = FALSE; if (last_sec != (time_t)system32.timers) { last_sec = system32.timers; @@ -3239,6 +3361,10 @@ bool CRYDevice::ry_run(void) void CRYDevice::ry_destroy(void) { +#if 1 +// client.destroy(); +#else nopoll_conn_close(conn); nopoll_ctx_unref(ctx); +#endif } diff --git a/das-dn/cmg/ry.h b/das-dn/cmg/ry.h index a35d94bb..74ffd5ac 100644 --- a/das-dn/cmg/ry.h +++ b/das-dn/cmg/ry.h @@ -11,8 +11,13 @@ #include #include -#include -#include +#if 1 + #include + using easywsclient::WebSocket; +#else + #include + #include +#endif #include #include @@ -27,6 +32,7 @@ #include "ytlog.h" #include "public.h" + #define MAX_MSG_COUNT 4096 typedef std::unordered_map uid2pidmap; @@ -66,6 +72,10 @@ typedef struct { typedef std::unordered_map pid2attrvectormap; +#include +#include +#include + class CRYDevice { public: @@ -75,6 +85,10 @@ public: BOOLEAN ry_init(const char*, const int, const char*, const char*); void ry_destroy(void); bool ry_run(void); + int sendMsg(std::string); + int recvMsg(std::string); + + void handle_message(const std::string & message); private: uid2pidmap uid2pid_map; unitname2servicemap unitname2service_map; @@ -92,15 +106,24 @@ private: struUnitStatic config_static_units[UNIT_NUM]; private: +#if 1 + std::queue m_SendQueue; + std::queue m_recvMsgQueue; + pthread_mutex_t m_SendQueueMutex; + pthread_mutex_t m_RecvQueueMutex; + + WebSocket::pointer m_ws; +#else noPollCtx *ctx; noPollConn *conn; - DWORD last_connect_sec = 0; - int status; - - int msg_count = 0; noPollMsg *msg[2048]; + int msg_count = 0; +#endif - bool m_dataAcquisitionReload = false; + DWORD last_connect_sec = 0; + int status; + + bool m_dataAcquisitionReload = false; char m_host[256] = {"127.0.0.1"}; int m_port = 7790; @@ -162,9 +185,11 @@ private: bool publishdeviceEventData(void); BOOLEAN publishYXBWData(int uid); BOOLEAN publishYCBWData(int uid); - +#if 1 +#else BOOLEAN websocket_msg_join(noPollMsg **msg, int msg_count, BYTE* &buffer, int &buffer_size); int websocket_write(const char * buffer, int buffer_len); +#endif bool publish_sensor_data(const std::string traceId, const char* command, const Json::Value payload); }; #endif //_RY_H_ \ No newline at end of file diff --git a/das-dn/comm/public.cpp b/das-dn/comm/public.cpp index 81c3840d..6e43f7b7 100644 --- a/das-dn/comm/public.cpp +++ b/das-dn/comm/public.cpp @@ -23,6 +23,8 @@ #include "json.h" +#include "ry.h" + #define PARAMTER_TYPE_MODBUS 1 #define PARAMTER_TYPE_104 2 #define PARAMTER_TYPE_9712 3 @@ -52,8 +54,12 @@ char configpath[MAX_PATH] = "./conf"; //配置文件 char configfile[MAX_PATH] = "./conf/config.db"; //配置文件 QWORD system_timems; - +#if 1 +//WebSocket::pointer g_conn; +CRYDevice* g_conn; +#else noPollConn *g_conn; +#endif Snowflake g_sf = {1, 1, 0, 0}; static eLogLevel eLevelMax = LOG_DEBUG; //LOG_DEBUG; diff --git a/das-dn/hostmodbusrtu/host_modbus_rtu.cpp b/das-dn/hostmodbusrtu/host_modbus_rtu.cpp index b2b564c9..825a080d 100644 --- a/das-dn/hostmodbusrtu/host_modbus_rtu.cpp +++ b/das-dn/hostmodbusrtu/host_modbus_rtu.cpp @@ -312,6 +312,7 @@ void CHostModbusRtuProcess::calc1(void) } } } + delete [] ycparam; } if (ymparam) { @@ -355,6 +356,7 @@ void CHostModbusRtuProcess::calc1(void) } } } + delete [] ymparam; } if (yxparam) { @@ -413,6 +415,7 @@ void CHostModbusRtuProcess::calc1(void) } } } + delete [] yxparam; } //按寄存器排序 pItem->AddFrames(ycframes, ymframes, yxframes); @@ -643,7 +646,7 @@ BOOLEAN CHostModbusRtuProcess::Run(void) GetData(tmpbuf, tmplen); DropData(tmplen); DisplayRxData(tmpbuf, tmplen, FALSE); - delete tmpbuf; + delete [] tmpbuf; tmpbuf = NULL; } if (WriteData(buffer, count + 2)) @@ -683,7 +686,7 @@ BOOLEAN CHostModbusRtuProcess::OnTimer(void) GetData(tmpbuf, tmplen); DropData(tmplen); DisplayRxData(tmpbuf, tmplen, FALSE); - delete tmpbuf; + delete [] tmpbuf; tmpbuf = NULL; } m_nNeedCount = 2; diff --git a/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.cpp b/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.cpp index d0f50d00..ec99f911 100644 --- a/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.cpp +++ b/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #define MODBUSP_READ_ID 100 //读取文件及文件夹ID #define MODBUSP_READ_ID_FUNCCODE 0x03 //读取文件及文件夹ID功能码。 @@ -22,8 +23,8 @@ typedef std::unordered_map datatypemap; typedef struct { - int start; - int length; + int start; + int length; } FIELDDES; struct { @@ -132,9 +133,8 @@ struct { { 2, 307 }, { 4, 308 }, { 4, 310 }, - { 2, 312 }, - { 4, 313 }, - { 2, 315 }, + { 4, 312 }, + { 4, 314 }, { 4, 316 }, { 4, 318 }, { 2, 320 }, @@ -185,9 +185,34 @@ struct { { 2, 365 }, { 2, 366 }, { 2, 367 }, - { 2, 368 } + { 2, 368 }, + { 2, 369 }, + { 2, 370 }, + { 2, 371 }, + { 2, 372 }, + { 2, 373 }, + { 2, 374 }, + { 2, 375 }, + { 2, 376 }, + { 2, 377 }, + { 4, 378 }, + { 4, 380 }, + { 4, 382 }, + { 2, 384 }, + { 2, 385 }, + { 2, 386 }, + { 2, 387 }, + { 2, 388 }, + { 2, 389 }, + { 2, 390 }, + { 2, 391 }, + { 2, 392 }, + { 2, 393 }, + { 2, 394 } }; +#if 1 +#else static int websocket_write(const noPollConn* conn, const char * buffer, int buffer_len) { int result; @@ -196,8 +221,12 @@ static int websocket_write(const noPollConn* conn, const char * buffer, int buff result = nopoll_conn_flush_writes((noPollConn *)conn, 2000000, result); return (result == buffer_len) ? 0 : -1; } - +#endif +#if 1 +static bool publish_sensor_data(const char* command, const Json::Value payload) +#else static bool publish_sensor_data(const noPollConn* conn, const char* command, const Json::Value payload) +#endif { Json::StreamWriterBuilder builder; builder["indentation"] = ""; @@ -216,7 +245,12 @@ static bool publish_sensor_data(const noPollConn* conn, const char* command, con jsonRoot["time"] = mtime; jsonRoot["data"] = payload; + //vLog(LOG_DEBUG, "here start to send.\n"); std::string outputConfig = Json::writeString(builder, jsonRoot); +#if 1 + g_conn->sendMsg(outputConfig); + //vLog(LOG_DEBUG, "outputConfig length is: %d\n", outputConfig.length()); +#else int rc = websocket_write(conn, outputConfig.c_str(), outputConfig.length()); //vLog(LOG_DEBUG, "send cmd: %s, payload: %d\n", command, outputConfig.length()/*, outputConfig.c_str()*/); if (rc != 0) { @@ -224,7 +258,7 @@ static bool publish_sensor_data(const noPollConn* conn, const char* command, con //插入数据库 return false; } - +#endif return true; } @@ -334,10 +368,10 @@ static BYTE GetUnitYXDataPos(int uid, int point) struUnit* pUnit; struUnitYX* pYX; - if (uid < 0 || uid >= UNIT_NUM) return (WORD)65535; + if (uid < 0 || uid >= UNIT_NUM) return (BYTE)0; pUnit = &config.units[uid]; - if (pUnit->yxcount <= 0) return (WORD)65535; - if (point < 0 || point >= pUnit->yxcount) return (WORD)65535; + if (pUnit->yxcount <= 0) return (BYTE)0; + if (point < 0 || point >= pUnit->yxcount) return (BYTE)0; pYX = &pUnit->yxs[point]; return (pYX->m_param[3]); } @@ -347,7 +381,7 @@ static BOOLEAN GetYCValue(const int order, const FIELDDES* fields, const char* p if (pData == NULL) return FALSE; if (fields == NULL) return FALSE; if (order < 0 || order >= sizeof(m_datalen_mbaddr) / sizeof(m_datalen_mbaddr[0])) return FALSE; - int start = fields[order].start; + int start = fields[order].start; if (fields[order].length == sizeof(DWORD)) { //4字节 value = *(DWORD *)(pData + start); @@ -369,7 +403,7 @@ static BOOLEAN GetYXValue(const int order, const FIELDDES* fields, const char* p if (fields == NULL) return FALSE; if (pos < 0 || pos >= 16) return FALSE; if (order < 0 || order >= sizeof(m_datalen_mbaddr) / sizeof(m_datalen_mbaddr[0])) return FALSE; - int start = fields[order].start; + int start = fields[order].start; if (fields[order].length == sizeof(WORD)) { WORD tmp = *(WORD *)(pData + start); @@ -383,7 +417,11 @@ static BOOLEAN GetYXValue(const int order, const FIELDDES* fields, const char* p return FALSE; } +#if 1 +static bool publishhistoryHighSpeedData(const int uid, const QWORD dt, const Json::Value values) +#else static bool publishhistoryHighSpeedData(const noPollConn* conn, const int uid, const QWORD dt, const Json::Value values) +#endif { if (uid < 0 || uid >= UNIT_NUM) return false; Json::Value root; @@ -391,12 +429,20 @@ static bool publishhistoryHighSpeedData(const noPollConn* conn, const int uid, c root["dataTime"] = (Json::Int64)dt; root["deviceId"] = static_units[uid].deviceId; root["values"] = values; +#if 1 + return publish_sensor_data("historyHighSpeedData", root); +#else return publish_sensor_data(conn, "historyHighSpeedData", root); +#endif } return false; } +#if 1 +static bool publishhistoryLowSpeedData(const int uid, const QWORD dt, const Json::Value values) +#else static bool publishhistoryLowSpeedData(const noPollConn* conn, const int uid, const QWORD dt, const Json::Value values) +#endif { if (uid < 0 || uid >= UNIT_NUM) return false; Json::Value root; @@ -405,7 +451,11 @@ static bool publishhistoryLowSpeedData(const noPollConn* conn, const int uid, co root["dataTime"] = (Json::Int64)(dt / 1000 * 1000); //取整 root["deviceId"] = static_units[uid].deviceId; root["values"] = values; +#if 1 + return publish_sensor_data("historyLowSpeedData", root); +#else return publish_sensor_data(conn, "historyLowSpeedData", root); +#endif } return false; } @@ -450,11 +500,11 @@ static int progressCallback(void* p, curl_off_t dltotal, curl_off_t dlnow, curl_ curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME_T, &curtime); if ((curtime - progress->lastruntime) >= 3000000) { progress->lastruntime = curtime; - fprintf(stderr, "Total time: %f\n", curtime); + vLog(LOG_DEBUG, "Total time: %f\n", curtime); } - fprintf(stderr, "UP: %ld bytes of %ld bytes, DOWN: %ld bytes of %ld bytes.\n", ulnow, ultotal, dlnow, dltotal); - if (ultotal) fprintf(stderr, "UP progress: %0.2f\n", float(ulnow /ultotal)); - if (dltotal) fprintf(stderr, "DOWN progress: %0.2f\n", float(dlnow /dltotal)); + vLog(LOG_DEBUG, "UP: %ld bytes of %ld bytes, DOWN: %ld bytes of %ld bytes.\n", ulnow, ultotal, dlnow, dltotal); + if (ultotal) vLog(LOG_DEBUG, "UP progress: %0.2f\n", float(ulnow /ultotal)); + if (dltotal) vLog(LOG_DEBUG, "DOWN progress: %0.2f\n", float(dlnow /dltotal)); return 0; } @@ -591,7 +641,6 @@ static void* ryftp_process(void* param) fields[len].start = reinterpret_cast(&t_data.iGenPower) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iGenPower); len++; - // fields[len].start = reinterpret_cast(&t_data.iWindSpeed) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iWindSpeed); len++; @@ -619,8 +668,8 @@ static void* ryftp_process(void* param) fields[len].start = reinterpret_cast(&t_data.iGenPower_1sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iGenPower_1sec); len++; - fields[len].start = reinterpret_cast(&t_data.iGenToruqe_1sec) - reinterpret_cast(&t_data); - fields[len].length = sizeof(t_data.iGenToruqe_1sec); + fields[len].start = reinterpret_cast(&t_data.iGenToruqe) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iGenToruqe); len++; fields[len].start = reinterpret_cast(&t_data.iRotorSpeed) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iRotorSpeed); @@ -634,8 +683,8 @@ static void* ryftp_process(void* param) fields[len].start = reinterpret_cast(&t_data.iActivePowerSetPointValue) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iActivePowerSetPointValue); len++; - fields[len].start = reinterpret_cast(&t_data.iCosPhiSetValue) - reinterpret_cast(&t_data); - fields[len].length = sizeof(t_data.iCosPhiSetValue); + fields[len].start = reinterpret_cast(&t_data.iReactivePowerSetPointValue) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iReactivePowerSetPointValue); len++; fields[len].start = reinterpret_cast(&t_data.iSetValueGenSpeed) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iSetValueGenSpeed); @@ -904,9 +953,6 @@ static void* ryftp_process(void* param) fields[len].start = reinterpret_cast(&t_data.iLostKWhOverall) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iLostKWhOverall); len++; - fields[len].start = reinterpret_cast(&t_data.FirstTriggeredCode) - reinterpret_cast(&t_data); - fields[len].length = sizeof(t_data.FirstTriggeredCode); - len++; fields[len].start = reinterpret_cast(&t_data.SCW001) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.SCW001); len++; @@ -1033,6 +1079,30 @@ static void* ryftp_process(void* param) fields[len].start = reinterpret_cast(&t_data.SCW042) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.SCW042); len++; + fields[len].start = reinterpret_cast(&t_data.SCW043) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW043); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW044) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW044); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW045) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW045); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW046) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW046); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW047) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW047); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW048) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW048); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW049) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW049); + len++; + fields[len].start = reinterpret_cast(&t_data.SCW050) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.SCW050); + len++; fields[len].start = reinterpret_cast(&t_data.iGenSpeed_10sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iGenSpeed_10sec); len++; @@ -1051,10 +1121,54 @@ static void* ryftp_process(void* param) fields[len].start = reinterpret_cast(&t_data.iWindSpeed_30sec) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iWindSpeed_30sec); len++; + fields[len].start = reinterpret_cast(&t_data.iWindSpeed_10min) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iWindSpeed_10min); + len++; fields[len].start = reinterpret_cast(&t_data.iAvailablePower) - reinterpret_cast(&t_data); fields[len].length = sizeof(t_data.iAvailablePower); len++; - + fields[len].start = reinterpret_cast(&t_data.FirstTriggeredCode) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.FirstTriggeredCode); + len++; + fields[len].start = reinterpret_cast(&t_data.FaultInformation) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.FaultInformation); + len++; + fields[len].start = reinterpret_cast(&t_data.WecRunCondition) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.WecRunCondition); + len++; + fields[len].start = reinterpret_cast(&t_data.iWindSpeedIEC) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iWindSpeedIEC); + len++; + fields[len].start = reinterpret_cast(&t_data.iWindSpeedIEC_30sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iWindSpeedIEC_30sec); + len++; + fields[len].start = reinterpret_cast(&t_data.iWindSpeedIEC_10min) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iWindSpeedIEC_10min); + len++; + fields[len].start = reinterpret_cast(&t_data.iYawPress) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iYawPress); + len++; + fields[len].start = reinterpret_cast(&t_data.iStandardAirDensity) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iStandardAirDensity); + len++; + fields[len].start = reinterpret_cast(&t_data.iAirDensity) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iAirDensity); + len++; + fields[len].start = reinterpret_cast(&t_data.iVibrationYFiltered) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iVibrationYFiltered); + len++; + fields[len].start = reinterpret_cast(&t_data.iVibrationZFiltered) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iVibrationZFiltered); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempGearWaterCool_1sec) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempGearWaterCool_1sec); + len++; + fields[len].start = reinterpret_cast(&t_data.PowerLimitSource) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.PowerLimitSource); + len++; + fields[len].start = reinterpret_cast(&t_data.iTempOutdoor_10min) - reinterpret_cast(&t_data); + fields[len].length = sizeof(t_data.iTempOutdoor_10min); + len++; //判断是否链接单元 int uid = mbt->GetUnitID(0); //默认只接一个设备 @@ -1107,22 +1221,27 @@ static void* ryftp_process(void* param) if (bReadCurrentFile) { //读取当前文件 + //vLog(LOG_DEBUG, "读取当前文件.\n"); snprintf(name, sizeof(name), "%s/%d", pathName, mbt->m_currentFileNo); snprintf(remote, sizeof(remote), "ftp://%s/%s/%d/%d", ipaddress, remotePath, mbt->m_currentDirNo, mbt->m_currentFileNo); } else { //读取未读的文件 + //vLog(LOG_DEBUG, "读取未读的文件.\n"); snprintf(name, sizeof(name), "%s/%d", pathName, mbt->m_lastReadFileNo); snprintf(remote, sizeof(remote), "ftp://%s/%s/%d/%d", ipaddress, remotePath, mbt->m_lastReadDirNo, mbt->m_lastReadFileNo); } struct memory chunk = {0}; // For storing the downloaded data int result = ftpget(remote, name, user, password, 3, &chunk); - if (result == CURLE_OK) { //成功,处理文件 - vLog(LOG_DEBUG, "get %s to local %s, with name: %s, and password: %s okay.\n", remote, name, user, password); + vLog(LOG_DEBUG, "get %s to local %s, with name: %s, and password: %s okay, and file length is: %d.\n", remote, name, user, password, chunk.size); ftpget_retry_count = 0; + if (chunk.size <= 0) { + vLog(LOG_DEBUG, "PLC文件生成未完成!\n"); + continue; + } struRYDeviceData *data = (struRYDeviceData *)chunk.response; unionCP56Time st; @@ -1153,7 +1272,11 @@ static void* ryftp_process(void* param) highspeedvalues[(const char *)config.units[uid].ycs[order].name] = 0.0f; } } +#if 1 + publishhistoryHighSpeedData(uid, unix_time, highspeedvalues); +#else publishhistoryHighSpeedData(g_conn, uid, unix_time, highspeedvalues); +#endif if (i % 25 == 0) { //40ms一个值,每25次位1s Json::Value lowspeedvalues; @@ -1184,7 +1307,11 @@ static void* ryftp_process(void* param) lowspeedvalues[(const char *)config.units[uid].yxs[order].name] = 0; } } +#if 1 + publishhistoryLowSpeedData(uid, unix_time, lowspeedvalues); +#else publishhistoryLowSpeedData(g_conn, uid, unix_time, lowspeedvalues); +#endif } } @@ -1212,6 +1339,7 @@ static void* ryftp_process(void* param) bReadCurrentFile = TRUE; } else if (result == CURLE_REMOTE_FILE_NOT_FOUND) { //文件不存在,尝试60次(1分钟,正常情况下PLC10s生成一个文件) + //vLog(LOG_DEBUG, "文件不存在, ftpget_retry_count is: %d\n", ftpget_retry_count); ftpget_retry_count++; if (ftpget_retry_count >= 60) { //重新通过modbus程序获取文件夹和最新文件信息 @@ -1223,6 +1351,10 @@ static void* ryftp_process(void* param) if (mbt->m_bHaveUnReadFile) { bReadCurrentFile = FALSE; } + } else if (result == CURLE_REMOTE_ACCESS_DENIED) { + vLog(LOG_DEBUG, "已读取完成所有未读的文件。\n"); + mbt->m_bHaveUnReadFile = FALSE; + bReadCurrentFile = TRUE; } } @@ -1531,8 +1663,8 @@ void CHostModbusTcpBFProcess::calc2(void) //组帧 for (n = 0; n < yccount; n++) { - WORD addr = MAKEWORD(ycparam[n].param[1], ycparam[n].param[2]); - if (addr >= 65535) continue; + WORD addr = MAKEWORD(ycparam[n].param[1], ycparam[n].param[2]); + if (addr >= 65535) continue; for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (ycframes[j].FuncCode == 0) @@ -1561,6 +1693,8 @@ void CHostModbusTcpBFProcess::calc2(void) } } } + + delete [] ycparam; } if (ymparam) { @@ -1574,8 +1708,8 @@ void CHostModbusTcpBFProcess::calc2(void) //组帧 for (n = 0; n < ymcount; n++) { - WORD addr = MAKEWORD(ymparam[n].param[1], ymparam[n].param[2]); - if (addr >= 65535) continue; + WORD addr = MAKEWORD(ymparam[n].param[1], ymparam[n].param[2]); + if (addr >= 65535) continue; for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (ymframes[j].FuncCode == 0) @@ -1604,6 +1738,8 @@ void CHostModbusTcpBFProcess::calc2(void) } } } + + delete [] ymparam; } if (yxparam) { @@ -1617,8 +1753,8 @@ void CHostModbusTcpBFProcess::calc2(void) //组帧 for (n = 0; n < yxcount; n++) { - WORD addr = MAKEWORD(yxparam[n].param[1], yxparam[n].param[2]); - if (addr >= 65535) continue; + WORD addr = MAKEWORD(yxparam[n].param[1], yxparam[n].param[2]); + if (addr >= 65535) continue; for (j = 0; j < MODBUS_RTU_AUTOMATIC_FRAME; j++) { if (yxframes[j].FuncCode == 0) @@ -1662,6 +1798,7 @@ void CHostModbusTcpBFProcess::calc2(void) } } } + delete [] yxparam; } //按寄存器排序 pItem->AddFrames(yxframes, ycframes, ymframes); @@ -2308,9 +2445,9 @@ BOOLEAN CHostModbusTcpBFProcess::OnReceiveIDData(CHostModbusTcpBFProcessItem *pI /* 1)、路径信息是否有效 byte; - 2)、当前文件夹路径名的后缀 dint,按照顺序增加1(转字符串时在前补0); - 3)、当前文件夹下最后新文件的编号 dint; - 4)、当前文件夹下第一个文件的编号 dint; + 2)、当前文件夹路径名的后缀 dint,按照顺序增加1(转字符串时在前补0); + 3)、当前文件夹下最后新文件的编号 dint; + 4)、当前文件夹下第一个文件的编号 dint; 5)、当前文件夹下文件个数 dint; */ //路径有效性判断 diff --git a/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.h b/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.h index 38bfd335..83260c64 100644 --- a/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.h +++ b/das-dn/hostmodbustcpbf/host_modbus_tcp_bf.h @@ -5,168 +5,194 @@ #include "modbus_def.h" #include +#if 1 +//#include "client.h" +#else #include #include +#endif #pragma pack(1) typedef struct { - QLONG localtime;// PLC本地时间 8 none 0.0001 毫秒 little endian 系统 - WORD iGenSpeed;// 发电机转速 2 200 0.1 转/分 40ms 控制系统 - WORD iGenPower;// 机组有功功率 2 201 0.1 千瓦 40ms 控制系统 - WORD iWindSpeed;// 风速 2 202 0.01 米/秒 40ms 气象 - WORD iVibrationY;// 机舱振动前后方向 2 203 0.001 米/秒^2 40ms 机舱 - WORD iVibrationZ;// 机舱振动左右方向 2 204 0.001 米/秒^2 40ms 机舱 - WORD iTurbineOperationMode;// 运行模式 2 205 1 需要解析 1s 控制系统 - WORD iBPLevel;// 刹车等级 2 206 1 需要解析 1s 控制系统 - WORD iYPLevel;// 偏航运行模式 2 207 1 需要解析 1s 控制系统 - WORD iWindSpeed_1sec;// 风速1秒均值 2 208 0.01 米/秒 1s 控制系统 - WORD iGenSpeed_1sec;// 发电机转速1秒均值 2 209 0.1 转/分 1s 控制系统 - WORD iGenPower_1sec;// 机组有功1秒均值 2 210 0.1 千瓦 1s 控制系统 - WORD iGenToruqe_1sec;// 发电机扭矩1秒均值 2 211 0.1 牛米 1s 控制系统 - WORD iRotorSpeed;// 风轮转速 2 212 0.1 转/分 1s 控制系统 - WORD iTheoreticalPower;// 理论有功功率 2 213 0.1 千瓦 1s 控制系统 - WORD iReactivePower;// 无功功率 2 214 0.1 千乏 1s 控制系统 - WORD iActivePowerSetPointValue;// 有功设定值 2 215 0.1 千瓦 1s 控制系统 - WORD iCosPhiSetValue;// 功率因数设定值 2 216 0.001 . 1s 控制系统 - WORD iSetValueGenSpeed;// 发电机转速设定值 2 217 0.1 转/分 1s 控制系统 - WORD iSetValuePitchAngle;// 桨叶角度设定值 2 218 0.01 度 1s 控制系统 - WORD iPitchAngle1RefValue;// 桨叶1角度给定 2 219 0.01 度 1s 控制系统 - WORD iPitchAngle2RefValue;// 桨叶2角度给定 2 220 0.01 度 1s 控制系统 - WORD iPitchAngle3RefValue;// 桨叶3角度给定 2 221 0.01 度 1s 控制系统 - WORD iPitchAngle1;// 桨叶1角度 2 222 0.01 度 1s 变桨系统 - WORD iPitchAngle2;// 桨叶2角度 2 223 0.01 度 1s 变桨系统 - WORD iPitchAngle3;// 桨叶3角度 2 224 0.01 度 1s 变桨系统 - WORD iVaneDirection;// 机舱方向 2 225 0.1 度 1s 气象 - WORD iWindDirection;// 风向(与机舱夹角) 2 226 0.1 度 1s 气象 - WORD StateWord01;// 状态字01 2 227 1 需要解析 1s 控制系统 详细解析见 状态字解析 - WORD StateWord02;// 状态字02 2 228 1 需要解析 1s 控制系统 - WORD StateWord03;// 状态字03 2 229 1 需要解析 1s 控制系统 - WORD StateWord04;// 状态字04 2 230 1 需要解析 1s 控制系统 - WORD StateWord05;// 状态字05 2 231 1 需要解析 1s 控制系统 - WORD StateWord06;// 状态字06 2 232 1 需要解析 1s 控制系统 - WORD StateWord07;// 状态字07 2 233 1 需要解析 1s 控制系统 - WORD StateWord08;// 状态字08 2 234 1 需要解析 1s 控制系统 - DWORD ActiveStatusCode01;// 故障代码01 4 235 1 需要解析 1s 控制系统 代表目前已经触发的故障代码类似:02(HH)04(HL)005(L) - DWORD ActiveStatusCode02;// 故障代码02 4 237 1 需要解析 1s 控制系统 详细解析见故障代码字解析 - DWORD ActiveStatusCode03;// 故障代码03 4 239 1 需要解析 1s 控制系统 - DWORD ActiveStatusCode04;// 故障代码04 4 241 1 需要解析 1s 控制系统 - DWORD ActiveStatusCode05;// 故障代码05 4 243 1 需要解析 1s 控制系统 - DWORD ActiveStatusCode06;// 故障代码06 4 245 1 需要解析 1s 控制系统 - DWORD ActiveStatusCode07;// 故障代码07 4 247 1 需要解析 1s 控制系统 - DWORD ActiveStatusCode08;// 故障代码08 4 249 1 需要解析 1s 控制系统 - WORD iFrequency;// 电网频率 2 251 0.01 赫兹 1s 电网 - WORD iUL1_690V;// 电网L1相电压 2 252 0.1 伏 1s 电网 - WORD iUL2_690V;// 电网L2相电压 2 253 0.1 伏 1s 电网 - WORD iUL3_690V;// 电网L3相电压 2 254 0.1 伏 1s 电网 - WORD iIL1_690V;// 电网L1相电流 2 255 0.1 安 1s 电网 - WORD iIL2_690V;// 电网L2相电流 2 256 0.1 安 1s 电网 - WORD iIL3_690V;// 电网L3相电流 2 257 0.1 安 1s 电网 - WORD iBlade1MotorCurrent;// 变桨电机1电流 2 258 0.1 安 1s 变桨系统 - WORD iBlade2MotorCurrent;// 变桨电机2电流 2 259 0.1 安 1s 变桨系统 - WORD iBlade3MotorCurrent;// 变桨电机3电流 2 260 0.1 安 1s 变桨系统 - WORD iPitchAngleBk1;// 备用桨叶角度1 2 261 0.01 度 1s 变桨系统 - WORD iPitchAngleBk2;// 备用桨叶角度2 2 262 0.01 度 1s 变桨系统 - WORD iPitchAngleBk3;// 备用桨叶角度3 2 263 0.01 度 1s 变桨系统 - WORD iCosPhi;// 并网点功率因数 2 264 0.001 . 1s 电网 - WORD iGearPressA;// 齿轮箱油压A 2 265 0.1 巴 1s 齿轮箱 - WORD iGearPressB;// 齿轮箱油压B 2 266 0.1 巴 1s 齿轮箱 - WORD iHydrPress;// 液压系统压力 2 267 0.1 巴 1s 液压系统 - WORD iNacellePositionLtd;// 机舱绝对方向 2 268 0.1 度 1s 机舱 - WORD iCableTwistTotal;// 总扭缆角度 2 269 0.1 度 1s 机舱 - WORD iNacellePositionTotal;// 机舱方向 2 270 0.1 度 1s 机舱 - WORD iTempOutdoor_1sec;// 环境温度 2 271 0.1 摄氏度 1s 环境 - WORD iTempHub_1sec;// 轮毂内温度 2 272 0.1 摄氏度 1s 轮毂 - WORD iTempNacelle_1sec;// 机舱内温度 2 273 0.1 摄氏度 1s 机舱 - WORD iTempTowerBase_1sec;// 塔基内温度 2 274 0.1 摄氏度 1s 塔基 - WORD iTempCabinetNacelle_1sec;// 机舱柜内温度 2 275 0.1 摄氏度 1s 机舱 - WORD iTempCabinetTowerBase_1sec;// 塔基柜内温度 2 276 0.1 摄氏度 1s 塔基 - WORD iTempTransformer690_400V_1sec;// 400伏变压器温度 2 277 0.1 摄氏度 1s 塔基 - WORD iTempMV_1sec;// 箱变温度 2 278 0.1 摄氏度 1s 箱变 - WORD iBlade1TempMotor_1sec;// 变桨电机1温度 2 279 0.1 摄氏度 1s 变桨系统 - WORD iBlade2TempMotor_1sec;// 变桨电机2温度 2 280 0.1 摄氏度 1s 变桨系统 - WORD iBlade3TempMotor_1sec;// 变桨电机3温度 2 281 0.1 摄氏度 1s 变桨系统 - WORD iBlade1TempBattBox_1sec;// 变桨电池柜1温度 2 282 0.1 摄氏度 1s 变桨系统 - WORD iBlade2TempBattBox_1sec;// 变桨电池柜2温度 2 283 0.1 摄氏度 1s 变桨系统 - WORD iBlade3TempBattBox_1sec;// 变桨电池柜3温度 2 284 0.1 摄氏度 1s 变桨系统 - WORD iTempCntr_1sec;// 变桨中控箱温度 2 285 0.1 摄氏度 1s 变桨系统 - WORD iBlade1TempInvBox_1sec;// 变桨逆变器1温度 2 286 0.1 摄氏度 1s 变桨系统 - WORD iBlade2TempInvBox_1sec;// 变桨逆变器2温度 2 287 0.1 摄氏度 1s 变桨系统 - WORD iBlade3TempInvBox_1sec;// 变桨逆变器3温度 2 288 0.1 摄氏度 1s 变桨系统 - WORD iBlade1TempPMMHeatsink_1sec;// 变桨PMM1散热器温度 2 289 0.1 摄氏度 1s 变桨系统 - WORD iBlade2TempPMMHeatsink_1sec;// 变桨PMM2散热器温度 2 290 0.1 摄氏度 1s 变桨系统 - WORD iBlade3TempPMMHeatsink_1sec;// 变桨PMM3散热器温度 2 291 0.1 摄氏度 1s 变桨系统 - WORD iBlade1TempPMCHeatsink_1sec;// 变桨PMC1散热器温度 2 292 0.1 摄氏度 1s 变桨系统 - WORD iBlade2TempPMCHeatsink_1sec;// 变桨PMC2散热器温度 2 293 0.1 摄氏度 1s 变桨系统 - WORD iBlade3TempPMCHeatsink_1sec;// 变桨PMC3散热器温度 2 294 0.1 摄氏度 1s 变桨系统 - WORD iTempRotorBearA_1sec;// 主轴承A温度 2 295 0.1 摄氏度 1s 传动链 - WORD iTempRotorBearB_1sec;// 主轴承B温度 2 296 0.1 摄氏度 1s 传动链 - WORD iTemp1GearOil_1sec;// 齿轮箱油温 2 297 0.1 摄氏度 1s 齿轮箱 - WORD iTempGearBearDE_1sec;// 齿轮箱驱动齿轴承温度 2 298 0.1 摄氏度 1s 齿轮箱 - WORD iTempGearBearNDE_1sec;// 齿轮箱非驱动侧轴承温度 2 299 0.1 摄氏度 1s 发电机 - WORD iTempGenBearDE_1sec;// 发电机驱动侧轴承温度 2 300 0.1 摄氏度 1s 发电机 - WORD iTempGenBearNDE_1sec;// 发电机非驱动侧轴承温度 2 301 0.1 摄氏度 1s 发电机 - WORD iTempGenStatorU_1sec;// 发电机绕组U温度 2 302 0.1 摄氏度 1s 发电机 - WORD iTempGenStatorV_1sec;// 发电机绕组V温度 2 303 0.1 摄氏度 1s 发电机 - WORD iTempGenStatorW_1sec;// 发电机绕组W温度 2 304 0.1 摄氏度 1s 发电机 - WORD iTempGenCoolingAir_1sec;// 发电机冷却风温度 2 305 0.1 摄氏度 1s 发电机 - WORD iAvailabillityToday;// 当天可利用率 2 306 0.001 . 1s 控制系统 - WORD iAvailabillityTotal;// 总可利用率 2 307 0.001 . 1s 控制系统 - DWORD iKWhThisDay;// 当天发电量 2 308 千瓦时 1s 控制系统 - DWORD iKWhOverall;// 总发电量 2 310 千瓦时 1s 控制系统 - WORD iOperationHoursDay;// 当天发电小时数 2 312 小时 1s 控制系统 - DWORD iOperationHoursOverall;// 总发电小时数 2 313 小时 1s 控制系统 - WORD iLostKWhThisDay;// 当天损失发电量 2 315 千瓦时 1s 控制系统 - DWORD iLostKWhOverall;// 总损失发电量 2 316 千瓦时 1s 控制系统 - DWORD FirstTriggeredCode;// 首触故障代码高 4 318 1 1s 控制系统 详细解析见故障代码字解析 - WORD SCW001;// 故障代码字01 2 320 1 1s 控制系统 - WORD SCW002;// 故障代码字02 2 321 1 1s 控制系统 - WORD SCW003;// 故障代码字03 2 322 1 1s 控制系统 - WORD SCW004;// 故障代码字04 2 323 1 1s 控制系统 - WORD SCW005;// 故障代码字05 2 324 1 1s 控制系统 - WORD SCW006;// 故障代码字06 2 325 1 1s 控制系统 - WORD SCW007;// 故障代码字07 2 326 1 1s 控制系统 - WORD SCW008;// 故障代码字08 2 327 1 1s 控制系统 - WORD SCW009;// 故障代码字09 2 328 1 1s 控制系统 - WORD SCW010;// 故障代码字10 2 329 1 1s 控制系统 - WORD SCW011;// 故障代码字11 2 330 1 1s 控制系统 - WORD SCW012;// 故障代码字12 2 331 1 1s 控制系统 - WORD SCW013;// 故障代码字13 2 332 1 1s 控制系统 - WORD SCW014;// 故障代码字14 2 333 1 1s 控制系统 - WORD SCW015;// 故障代码字15 2 334 1 1s 控制系统 - WORD SCW016;// 故障代码字16 2 335 1 1s 控制系统 - WORD SCW017;// 故障代码字17 2 336 1 1s 控制系统 - WORD SCW018;// 故障代码字18 2 337 1 1s 控制系统 - WORD SCW019;// 故障代码字19 2 338 1 1s 控制系统 - WORD SCW020;// 故障代码字20 2 339 1 1s 控制系统 - WORD SCW021;// 故障代码字21 2 340 1 1s 控制系统 - WORD SCW022;// 故障代码字22 2 341 1 1s 控制系统 - WORD SCW023;// 故障代码字23 2 342 1 1s 控制系统 - WORD SCW024;// 故障代码字24 2 343 1 1s 控制系统 - WORD SCW025;// 故障代码字25 2 344 1 1s 控制系统 - WORD SCW026;// 故障代码字26 2 345 1 1s 控制系统 - WORD SCW027;// 故障代码字27 2 346 1 1s 控制系统 - WORD SCW028;// 故障代码字28 2 347 1 1s 控制系统 - WORD SCW029;// 故障代码字29 2 348 1 1s 控制系统 - WORD SCW030;// 故障代码字30 2 349 1 1s 控制系统 - WORD SCW031;// 故障代码字31 2 350 1 1s 控制系统 - WORD SCW032;// 故障代码字32 2 351 1 1s 控制系统 - WORD SCW033;// 故障代码字33 2 352 1 1s 控制系统 - WORD SCW034;// 故障代码字34 2 353 1 1s 控制系统 - WORD SCW035;// 故障代码字35 2 354 1 1s 控制系统 - WORD SCW036;// 故障代码字36 2 355 1 1s 控制系统 - WORD SCW037;// 故障代码字37 2 356 1 1s 控制系统 - WORD SCW038;// 故障代码字38 2 357 1 1s 控制系统 - WORD SCW039;// 故障代码字39 2 358 1 1s 控制系统 - WORD SCW040;// 故障代码字40 2 359 1 1s 控制系统 - WORD SCW041;// 故障代码字41 2 360 1 1s 控制系统 - WORD SCW042;// 故障代码字42 2 361 1 1s 控制系统 - WORD iGenSpeed_10sec;// 发电机转速10秒均值 2 362 - WORD iGenSpeed_30sec;// 发电机转速30秒均值 2 363 - WORD iGenPower_10sec;// 机组有功10秒均值 2 364 - WORD iGenPower_30sec;// 机组有功30秒均值 2 365 - WORD iWindSpeed_10sec;// 风速10秒均值 2 366 - WORD iWindSpeed_30sec;// 风速30秒均值 2 367 - WORD iAvailablePower;// 可用有功功率 2 368 + QLONG localtime;// PLC本地时间 8 none 0.0001 毫秒 little endian 系统 + WORD iGenSpeed;//发电机转速 2 200 0.1 转/分 40ms 控制系统 + WORD iGenPower;//机组有功功率 2 201 0.1 千瓦 40ms 控制系统 + WORD iWindSpeed;//风速 2 202 0.01 米/秒 40ms 气象 + WORD iVibrationY;//机舱振动前后方向 2 203 0.001 米/秒^2 40ms 机舱 + WORD iVibrationZ;//机舱振动左右方向 2 204 0.001 米/秒^2 40ms 机舱 + WORD iTurbineOperationMode;//运行模式 2 205 1 需要解析 1s 控制系统 + WORD iBPLevel;//刹车等级 2 206 1 需要解析 1s 控制系统 + WORD iYPLevel;//偏航运行模式 2 207 1 需要解析 1s 控制系统 + WORD iWindSpeed_1sec;//风速1秒均值 2 208 0.01 米/秒 1s 气象 + WORD iGenSpeed_1sec;//发电机转速1秒均值 2 209 0.1 转/分 1s 控制系统 + WORD iGenPower_1sec;//机组有功1秒均值 2 210 0.1 千瓦 1s 控制系统 + WORD iGenToruqe;//发电机扭矩1秒均值 2 211 0.1 牛米 1s 控制系统 + WORD iRotorSpeed;//风轮转速 2 212 0.1 转/分 1s 控制系统 + WORD iTheoreticalPower;//理论有功功率 2 213 0.1 千瓦 1s 控制系统 + WORD iReactivePower;//无功功率 2 214 0.1 千乏 1s 控制系统 + WORD iActivePowerSetPointValue;//有功设定值 2 215 0.1 千瓦 1s 控制系统 + WORD iReactivePowerSetPointValue;//无功设定值 2 216 0.1 千乏 1s 控制系统 + WORD iSetValueGenSpeed;//发电机转速设定值 2 217 0.1 转/分 1s 控制系统 + WORD iSetValuePitchAngle;//桨叶角度设定值 2 218 0.01 度 1s 控制系统 + WORD iPitchAngle1RefValue;//桨叶1角度给定 2 219 0.01 度 1s 控制系统 + WORD iPitchAngle2RefValue;//桨叶2角度给定 2 220 0.01 度 1s 控制系统 + WORD iPitchAngle3RefValue;//桨叶3角度给定 2 221 0.01 度 1s 控制系统 + WORD iPitchAngle1;//桨叶1角度 2 222 0.01 度 1s 变桨系统 + WORD iPitchAngle2;//桨叶2角度 2 223 0.01 度 1s 变桨系统 + WORD iPitchAngle3;//桨叶3角度 2 224 0.01 度 1s 变桨系统 + WORD iVaneDirection;//机舱方向 2 225 0.1 度 1s 气象 + WORD iWindDirection;//风向(与机舱夹角) 2 226 0.1 度 1s 气象 + WORD StateWord01;//状态字01 2 227 1 需要解析 1s 控制系统 + WORD StateWord02;//状态字02 2 228 1 需要解析 1s 控制系统 + WORD StateWord03;//状态字03 2 229 1 需要解析 1s 控制系统 + WORD StateWord04;//状态字04 2 230 1 需要解析 1s 控制系统 + WORD StateWord05;//状态字05 2 231 1 需要解析 1s 控制系统 + WORD StateWord06;//状态字06 2 232 1 需要解析 1s 控制系统 + WORD StateWord07;//状态字07 2 233 1 需要解析 1s 控制系统 + WORD StateWord08;//状态字08 2 234 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode01;//故障代码01 4 235 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode02;//故障代码02 4 237 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode03;//故障代码03 4 239 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode04;//故障代码04 4 241 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode05;//故障代码05 4 243 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode06;//故障代码06 4 245 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode07;//故障代码07 4 247 1 需要解析 1s 控制系统 + DWORD ActiveStatusCode08;//故障代码08 4 249 1 需要解析 1s 控制系统 + WORD iFrequency;//电网频率 2 251 0.01 赫兹 1s 电网 + WORD iUL1_690V;//电网L1相电压 2 252 0.1 伏 1s 电网 + WORD iUL2_690V;//电网L2相电压 2 253 0.1 伏 1s 电网 + WORD iUL3_690V;//电网L3相电压 2 254 0.1 伏 1s 电网 + WORD iIL1_690V;//电网L1相电流 2 255 0.1 安 1s 电网 + WORD iIL2_690V;//电网L2相电流 2 256 0.1 安 1s 电网 + WORD iIL3_690V;//电网L3相电流 2 257 0.1 安 1s 电网 + WORD iBlade1MotorCurrent;//变桨电机1电流 2 258 0.1 安 1s 变桨系统 + WORD iBlade2MotorCurrent;//变桨电机2电流 2 259 0.1 安 1s 变桨系统 + WORD iBlade3MotorCurrent;//变桨电机3电流 2 260 0.1 安 1s 变桨系统 + WORD iPitchAngleBk1;//备用桨叶角度1 2 261 0.01 度 1s 变桨系统 + WORD iPitchAngleBk2;//备用桨叶角度2 2 262 0.01 度 1s 变桨系统 + WORD iPitchAngleBk3;//备用桨叶角度3 2 263 0.01 度 1s 变桨系统 + WORD iCosPhi;//并网点功率因数 2 264 0.001 . 1s 电网 + WORD iGearPressA;//齿轮箱油压A 2 265 0.1 巴 1s 齿轮箱 + WORD iGearPressB;//齿轮箱油压B 2 266 0.1 巴 1s 齿轮箱 + WORD iHydrPress;//液压系统压力 2 267 0.1 巴 1s 液压系统 + WORD iNacellePositionLtd;//机舱绝对方向 2 268 0.1 度 1s 机舱 + WORD iCableTwistTotal;//总扭缆角度 2 269 0.1 度 1s 机舱 + WORD iNacellePositionTotal;//机舱方向 2 270 0.1 度 1s 机舱 + WORD iTempOutdoor_1sec;//环境温度 2 271 0.1 摄氏度 1s 环境 + WORD iTempHub_1sec;//轮毂内温度 2 272 0.1 摄氏度 1s 轮毂 + WORD iTempNacelle_1sec;//机舱内温度 2 273 0.1 摄氏度 1s 机舱 + WORD iTempTowerBase_1sec;//塔基内温度 2 274 0.1 摄氏度 1s 塔基 + WORD iTempCabinetNacelle_1sec;//机舱柜内温度 2 275 0.1 摄氏度 1s 机舱 + WORD iTempCabinetTowerBase_1sec;//塔基柜内温度 2 276 0.1 摄氏度 1s 塔基 + WORD iTempTransformer690_400V_1sec;//400伏变压器温度 2 277 0.1 摄氏度 1s 塔基 + WORD iTempMV_1sec;//箱变温度 2 278 0.1 摄氏度 1s 箱变 + WORD iBlade1TempMotor_1sec;//变桨电机1温度 2 279 0.1 摄氏度 1s 变桨系统 + WORD iBlade2TempMotor_1sec;//变桨电机2温度 2 280 0.1 摄氏度 1s 变桨系统 + WORD iBlade3TempMotor_1sec;//变桨电机3温度 2 281 0.1 摄氏度 1s 变桨系统 + WORD iBlade1TempBattBox_1sec;//变桨电池柜1温度 2 282 0.1 摄氏度 1s 变桨系统 + WORD iBlade2TempBattBox_1sec;//变桨电池柜2温度 2 283 0.1 摄氏度 1s 变桨系统 + WORD iBlade3TempBattBox_1sec;//变桨电池柜3温度 2 284 0.1 摄氏度 1s 变桨系统 + WORD iTempCntr_1sec;//变桨中控箱温度 2 285 0.1 摄氏度 1s 变桨系统 + WORD iBlade1TempInvBox_1sec;//变桨逆变器1温度 2 286 0.1 摄氏度 1s 变桨系统 + WORD iBlade2TempInvBox_1sec;//变桨逆变器2温度 2 287 0.1 摄氏度 1s 变桨系统 + WORD iBlade3TempInvBox_1sec;//变桨逆变器3温度 2 288 0.1 摄氏度 1s 变桨系统 + WORD iBlade1TempPMMHeatsink_1sec;//变桨PMM1散热器温度 2 289 0.1 摄氏度 1s 变桨系统 + WORD iBlade2TempPMMHeatsink_1sec;//变桨PMM2散热器温度 2 290 0.1 摄氏度 1s 变桨系统 + WORD iBlade3TempPMMHeatsink_1sec;//变桨PMM3散热器温度 2 291 0.1 摄氏度 1s 变桨系统 + WORD iBlade1TempPMCHeatsink_1sec;//变桨PMC1散热器温度 2 292 0.1 摄氏度 1s 变桨系统 + WORD iBlade2TempPMCHeatsink_1sec;//变桨PMC2散热器温度 2 293 0.1 摄氏度 1s 变桨系统 + WORD iBlade3TempPMCHeatsink_1sec;//变桨PMC3散热器温度 2 294 0.1 摄氏度 1s 变桨系统 + WORD iTempRotorBearA_1sec;//主轴承A温度 2 295 0.1 摄氏度 1s 传动链 + WORD iTempRotorBearB_1sec;//主轴承B温度 2 296 0.1 摄氏度 1s 传动链 + WORD iTemp1GearOil_1sec;//齿轮箱油温 2 297 0.1 摄氏度 1s 齿轮箱 + WORD iTempGearBearDE_1sec;//齿轮箱驱动齿轴承温度 2 298 0.1 摄氏度 1s 齿轮箱 + WORD iTempGearBearNDE_1sec;//齿轮箱非驱动侧轴承温度 2 299 0.1 摄氏度 1s 发电机 + WORD iTempGenBearDE_1sec;//发电机驱动侧轴承温度 2 300 0.1 摄氏度 1s 发电机 + WORD iTempGenBearNDE_1sec;//发电机非驱动侧轴承温度 2 301 0.1 摄氏度 1s 发电机 + WORD iTempGenStatorU_1sec;//发电机绕组U温度 2 302 0.1 摄氏度 1s 发电机 + WORD iTempGenStatorV_1sec;//发电机绕组V温度 2 303 0.1 摄氏度 1s 发电机 + WORD iTempGenStatorW_1sec;//发电机绕组W温度 2 304 0.1 摄氏度 1s 发电机 + WORD iTempGenCoolingAir_1sec;//发电机冷却风温度 2 305 0.1 摄氏度 1s 发电机 + WORD iAvailabillityToday;//当天可利用率 2 306 0.001 . 1s 控制系统 + WORD iAvailabillityTotal;//总可利用率 2 307 0.001 . 1s 控制系统 + DWORD iKWhThisDay;//当天发电量 4 308 千瓦时 1s 控制系统 + DWORD iKWhOverall;//总发电量 4 310 千瓦时 1s 控制系统 + DWORD iOperationHoursDay;//当天发电小时数 4 312 小时 1s 控制系统 + DWORD iOperationHoursOverall;//总发电小时数 4 314 小时 1s 控制系统 + DWORD iLostKWhThisDay;//当天损失发电量 4 316 千瓦时 1s 控制系统 + DWORD iLostKWhOverall;//总损失发电量 4 318 千瓦时 1s 控制系统 + WORD SCW001;//故障代码字01 2 320 1 1s 控制系统 + WORD SCW002;//故障代码字02 2 321 1 1s 控制系统 + WORD SCW003;//故障代码字03 2 322 1 1s 控制系统 + WORD SCW004;//故障代码字04 2 323 1 1s 控制系统 + WORD SCW005;//故障代码字05 2 324 1 1s 控制系统 + WORD SCW006;//故障代码字06 2 325 1 1s 控制系统 + WORD SCW007;//故障代码字07 2 326 1 1s 控制系统 + WORD SCW008;//故障代码字08 2 327 1 1s 控制系统 + WORD SCW009;//故障代码字09 2 328 1 1s 控制系统 + WORD SCW010;//故障代码字10 2 329 1 1s 控制系统 + WORD SCW011;//故障代码字11 2 330 1 1s 控制系统 + WORD SCW012;//故障代码字12 2 331 1 1s 控制系统 + WORD SCW013;//故障代码字13 2 332 1 1s 控制系统 + WORD SCW014;//故障代码字14 2 333 1 1s 控制系统 + WORD SCW015;//故障代码字15 2 334 1 1s 控制系统 + WORD SCW016;//故障代码字16 2 335 1 1s 控制系统 + WORD SCW017;//故障代码字17 2 336 1 1s 控制系统 + WORD SCW018;//故障代码字18 2 337 1 1s 控制系统 + WORD SCW019;//故障代码字19 2 338 1 1s 控制系统 + WORD SCW020;//故障代码字20 2 339 1 1s 控制系统 + WORD SCW021;//故障代码字21 2 340 1 1s 控制系统 + WORD SCW022;//故障代码字22 2 341 1 1s 控制系统 + WORD SCW023;//故障代码字23 2 342 1 1s 控制系统 + WORD SCW024;//故障代码字24 2 343 1 1s 控制系统 + WORD SCW025;//故障代码字25 2 344 1 1s 控制系统 + WORD SCW026;//故障代码字26 2 345 1 1s 控制系统 + WORD SCW027;//故障代码字27 2 346 1 1s 控制系统 + WORD SCW028;//故障代码字28 2 347 1 1s 控制系统 + WORD SCW029;//故障代码字29 2 348 1 1s 控制系统 + WORD SCW030;//故障代码字30 2 349 1 1s 控制系统 + WORD SCW031;//故障代码字31 2 350 1 1s 控制系统 + WORD SCW032;//故障代码字32 2 351 1 1s 控制系统 + WORD SCW033;//故障代码字33 2 352 1 1s 控制系统 + WORD SCW034;//故障代码字34 2 353 1 1s 控制系统 + WORD SCW035;//故障代码字35 2 354 1 1s 控制系统 + WORD SCW036;//故障代码字36 2 355 1 1s 控制系统 + WORD SCW037;//故障代码字37 2 356 1 1s 控制系统 + WORD SCW038;//故障代码字38 2 357 1 1s 控制系统 + WORD SCW039;//故障代码字39 2 358 1 1s 控制系统 + WORD SCW040;//故障代码字40 2 359 1 1s 控制系统 + WORD SCW041;//故障代码字41 2 360 1 1s 控制系统 + WORD SCW042;//故障代码字42 2 361 1 1s 控制系统 + WORD SCW043;//故障代码字43 2 362 1 1s 控制系统 + WORD SCW044;//故障代码字44 2 363 1 1s 控制系统 + WORD SCW045;//故障代码字45 2 364 1 1s 控制系统 + WORD SCW046;//故障代码字46 2 365 1 1s 控制系统 + WORD SCW047;//故障代码字47 2 366 1 1s 控制系统 + WORD SCW048;//故障代码字48 2 367 1 1s 控制系统 + WORD SCW049;//故障代码字49 2 368 1 1s 控制系统 + WORD SCW050;//故障代码字50 2 369 1 1s 控制系统 + WORD iGenSpeed_10sec;//发电机转速10秒均值 2 370 0.1 转/分 1s 控制系统 + WORD iGenSpeed_30sec;//发电机转速30秒均值 2 371 0.1 转/分 1s 控制系统 + WORD iGenPower_10sec;//机组有功10秒均值 2 372 0.1 千瓦 1s 控制系统 + WORD iGenPower_30sec;//机组有功30秒均值 2 373 0.1 千瓦 1s 控制系统 + WORD iWindSpeed_10sec;//风速10秒均值 2 374 0.01 米/秒 1s 气象 + WORD iWindSpeed_30sec;//风速30秒均值 2 375 0.01 米/秒 1s 气象 + WORD iWindSpeed_10min;//风速10分钟均值 2 376 0.01 米/秒 1s 气象 + WORD iAvailablePower;//可用有功功率 2 377 0.1 千瓦 1s 控制系统 + DWORD FirstTriggeredCode;//首触故障代码 4 378 1 1s 控制系统 + DWORD FaultInformation;//故障信息 4 380 1 1s 控制系统 + DWORD WecRunCondition;//机组运行状态机状态 4 382 1 1s 控制系统 + WORD iWindSpeedIEC;//标准化风速 2 384 0.01 米/秒 1s 控制系统 + WORD iWindSpeedIEC_30sec;//标准化风速30秒均值 2 385 0.01 米/秒 1s 控制系统 + WORD iWindSpeedIEC_10min;//标准化风速10分钟均值 2 386 0.01 米/秒 1s 控制系统 + WORD iYawPress;//偏航系统压力 2 387 0.1 巴 1s 液压系统 + WORD iStandardAirDensity;//标准空气密度 2 388 0.001 千克/米^3 1s 气象 + WORD iAirDensity;//实时空气密度 2 389 0.001 1s 气象 + WORD iVibrationYFiltered;//机舱振动前后方向滤波值 2 390 0.001 米/秒^2 1s 机舱 + WORD iVibrationZFiltered;//机舱振动左右方向滤波值 2 391 0.001 米/秒^2 1s 机舱 + WORD iTempGearWaterCool_1sec;//齿轮箱水冷温度 2 392 0.1 摄氏度 1s 齿轮箱 + WORD PowerLimitSource;//限功率原因 2 393 1 1s 控制系统 + WORD iTempOutdoor_10min;//环境温度十分钟均值 2 394 0.1 摄氏度 1s 环境 } struRYDeviceData; #pragma pack() diff --git a/das-dn/inc/public.h b/das-dn/inc/public.h index 36e50592..7f472ead 100644 --- a/das-dn/inc/public.h +++ b/das-dn/inc/public.h @@ -40,8 +40,13 @@ typedef int SOCKET; #include #include #include "zlog/zlog.h" +#if 1 +//#include "easywsclient.hpp" +//using easywsclient::WebSocket; +#else #include #include +#endif #define MEMERY_1M 65536 //设置位64K #define DELAY_RUN 5000 @@ -1342,7 +1347,13 @@ extern struNodeOption nodes; extern char configpath[MAX_PATH]; //配置文件所在目录 extern char configfile[MAX_PATH]; //配置文件 +#if 1 +//extern WebSocket::pointer g_conn; +class CRYDevice; +extern CRYDevice* g_conn; +#else extern noPollConn *g_conn; +#endif typedef struct { //网络配置信息 diff --git a/das-dn/inc/websockets/client.h b/das-dn/inc/websockets/client.h new file mode 100644 index 00000000..8a342294 --- /dev/null +++ b/das-dn/inc/websockets/client.h @@ -0,0 +1,95 @@ +#ifndef _CLIENT_ +#define _CLIENT_ + +#include +#include +#include +#include +#include +//#include +#include +#include +#include "zjdtypes.h" + +using namespace std; + +#define MAX_PAYLOAD_SIZE 20 * 1024 + +typedef enum +{ + CLIENT_IDLE, + CLIENT_CONNECTING, + CLIENT_CONNECTED, + CLIENT_AWAITING_SEND, + ClIENT_COMPLETE_RECV, + CLIENT_CLOSED +} TSTAT; + +typedef struct session_data { + int msg_count; + unsigned char buf[LWS_PRE + MAX_PAYLOAD_SIZE]; + int len; +} session_data, *SESSIONDATA; + +class CWSClient +{ +public: + CWSClient(string url); + CWSClient(void); + ~CWSClient(); + + void init(); + void init(std::string url); + int set_ssl(const char* ca_filepath, const char* server_cert_filepath, const char*server_private_key_filepath, int ssl_conn); + bool create(); + bool connect(int ssl_conn); + bool reconnect(void); + bool run(int wait_time); + int send(string data); + int recv(std::string data); + int recvMsg(void); + int recvFrame(std::string); + int getRecvSize(); + string getRecvMsg(); + void popRecvMsg(); +#if 0 + void setLogLevel(int level); +#endif + TSTAT getConnStat(); + void destroy(); + void setEnd(bool flag); + + DWORD getConnectTime(void) { return m_reconnect_attempts; } + void setConnectTime(DWORD tm) { m_reconnect_attempts = tm; } + + friend void* WSpthreadFunc(void* arg); + friend int callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); + +private: + + string m_cacheFile; + bool m_end; + int m_waittime; + pthread_t m_threadID; + queue m_sendMsgQueue; + queue m_recvMsgQueue; + queue m_recvFrameQueue; + SESSIONDATA m_session_data; + string m_url; + const char* m_prot; + const char* m_ads; + const char* m_path; + int m_port; + TSTAT m_stat; + int m_logLevel; + DWORD m_reconnect_attempts; + struct lws_protocols * m_protocols; + struct lws_context_creation_info m_ctx_info; /* 用于创建vhost或者context的参数 */ + struct lws_context * m_context; + struct lws_client_connect_info m_conn_info; + struct lws * m_wsi; + pthread_mutex_t m_rmutex; + pthread_mutex_t m_smutex; +}; + +#endif diff --git a/das-dn/inc/websockets/easywsclient.hpp b/das-dn/inc/websockets/easywsclient.hpp new file mode 100644 index 00000000..b7a1781a --- /dev/null +++ b/das-dn/inc/websockets/easywsclient.hpp @@ -0,0 +1,73 @@ +#ifndef EASYWSCLIENT_HPP_20170819_MIOFVASDTNUASZDQPLFD +#define EASYWSCLIENT_HPP_20170819_MIOFVASDTNUASZDQPLFD + +// This code comes from: +// https://github.com/dhbaird/easywsclient +// +// To get the latest version: +// wget https://raw.github.com/dhbaird/easywsclient/master/easywsclient.hpp +// wget https://raw.github.com/dhbaird/easywsclient/master/easywsclient.cpp + +#include +#include +#include + +namespace easywsclient { + +struct Callback_Imp { virtual void operator()(const std::string& message) = 0; }; +struct BytesCallback_Imp { virtual void operator()(const std::vector& message) = 0; }; + +class WebSocket { + public: + typedef WebSocket * pointer; + typedef enum readyStateValues { CLOSING, CLOSED, CONNECTING, OPEN } readyStateValues; + + // Factories: + static pointer create_dummy(); + static pointer from_url(const std::string& url, const std::string& origin = std::string()); + static pointer from_url_no_mask(const std::string& url, const std::string& origin = std::string()); + + // Interfaces: + virtual ~WebSocket() { } + virtual void poll(int timeout = 0) = 0; // timeout in milliseconds + virtual void send(const std::string& message) = 0; + virtual void sendBinary(const std::string& message) = 0; + virtual void sendBinary(const std::vector& message) = 0; + virtual void sendPing() = 0; + virtual void close() = 0; + virtual readyStateValues getReadyState() const = 0; + + template + void dispatch(Callable callable) + // For callbacks that accept a string argument. + { // N.B. this is compatible with both C++11 lambdas, functors and C function pointers + struct _Callback : public Callback_Imp { + Callable& callable; + _Callback(Callable& callable) : callable(callable) { } + void operator()(const std::string& message) { callable(message); } + }; + _Callback callback(callable); + _dispatch(callback); + } + + template + void dispatchBinary(Callable callable) + // For callbacks that accept a std::vector argument. + { // N.B. this is compatible with both C++11 lambdas, functors and C function pointers + struct _Callback : public BytesCallback_Imp { + Callable& callable; + _Callback(Callable& callable) : callable(callable) { } + void operator()(const std::vector& message) { callable(message); } + }; + _Callback callback(callable); + _dispatchBinary(callback); + } + + protected: + virtual void _dispatch(Callback_Imp& callable) = 0; + virtual void _dispatchBinary(BytesCallback_Imp& callable) = 0; +}; + +} // namespace easywsclient + +#endif /* EASYWSCLIENT_HPP_20120819_MIOFVASDTNUASZDQPLFD */ diff --git a/das-dn/third_party/nopoll/nopoll_conn.c b/das-dn/third_party/nopoll/nopoll_conn.c index 4873cd62..db4ba20c 100644 --- a/das-dn/third_party/nopoll/nopoll_conn.c +++ b/das-dn/third_party/nopoll/nopoll_conn.c @@ -3383,7 +3383,7 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn) msg->payload_size = nopoll_get_16bit (buffer + 2); nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "Received (%d) bytes in header (size %d) for payload size indication, which finally is: %d", bytes, header_size,(int) msg->payload_size); - fprintf(stderr, "Received (%d) bytes in header (size %d) for payload size indication, which finally is: %d\n", bytes, header_size,(int) msg->payload_size); + //fprintf(stderr, "Received (%d) bytes in header (size %d) for payload size indication, which finally is: %d\n", bytes, header_size,(int) msg->payload_size); } else if (msg->payload_size == 127) { /* read more content (next 8 bytes) */ @@ -3479,8 +3479,7 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn) nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "Detected incoming websocket frame: fin(%d), op_code(%d), is_masked(%d), payload size(%ld), mask=%d", msg->has_fin, msg->op_code, msg->is_masked, msg->payload_size, nopoll_get_32bit (msg->mask)); - fprintf(stderr, "Detected incoming websocket frame: fin(%d), op_code(%d), is_masked(%d), payload size(%ld), mask=%d\n", - msg->has_fin, msg->op_code, msg->is_masked, msg->payload_size, nopoll_get_32bit (msg->mask)); + //fprintf(stderr, "Detected incoming websocket frame: fin(%d), op_code(%d), is_masked(%d), payload size(%ld), mask=%d\n", msg->has_fin, msg->op_code, msg->is_masked, msg->payload_size, nopoll_get_32bit (msg->mask)); /* check payload size */ if (msg->payload_size == 0) { diff --git a/das-dn/third_party/websockets/easywsclient.cpp b/das-dn/third_party/websockets/easywsclient.cpp new file mode 100644 index 00000000..83970860 --- /dev/null +++ b/das-dn/third_party/websockets/easywsclient.cpp @@ -0,0 +1,527 @@ + +#ifdef _WIN32 + #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) + #define _CRT_SECURE_NO_WARNINGS // _CRT_SECURE_NO_WARNINGS for sscanf errors in MSVC2013 Express + #endif + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #include + #include + #include + #pragma comment( lib, "ws2_32" ) + #include + #include + #include + #include + #include + #ifndef _SSIZE_T_DEFINED + typedef int ssize_t; + #define _SSIZE_T_DEFINED + #endif + #ifndef _SOCKET_T_DEFINED + typedef SOCKET socket_t; + #define _SOCKET_T_DEFINED + #endif + #ifndef snprintf + #define snprintf _snprintf_s + #endif + #if _MSC_VER >=1600 + // vs2010 or later + #include + #else + typedef __int8 int8_t; + typedef unsigned __int8 uint8_t; + typedef __int32 int32_t; + typedef unsigned __int32 uint32_t; + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + #endif + #define socketerrno WSAGetLastError() + #define SOCKET_EAGAIN_EINPROGRESS WSAEINPROGRESS + #define SOCKET_EWOULDBLOCK WSAEWOULDBLOCK +#else + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #ifndef _SOCKET_T_DEFINED + typedef int socket_t; + #define _SOCKET_T_DEFINED + #endif + #ifndef INVALID_SOCKET + #define INVALID_SOCKET (-1) + #endif + #ifndef SOCKET_ERROR + #define SOCKET_ERROR (-1) + #endif + #define closesocket(s) ::close(s) + #include + #define socketerrno errno + #define SOCKET_EAGAIN_EINPROGRESS EAGAIN + #define SOCKET_EWOULDBLOCK EWOULDBLOCK +#endif + +#include +#include + +#include "easywsclient.hpp" +#include "public.h" + +using easywsclient::Callback_Imp; +using easywsclient::BytesCallback_Imp; + +namespace { // private module-only namespace + +socket_t hostname_connect(const std::string& hostname, int port) { + struct addrinfo hints; + struct addrinfo *result; + struct addrinfo *p; + int ret; + socket_t sockfd = INVALID_SOCKET; + char sport[16]; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + snprintf(sport, 16, "%d", port); + if ((ret = getaddrinfo(hostname.c_str(), sport, &hints, &result)) != 0) + { + vLog(LOG_ERROR, "getaddrinfo: %s\n", gai_strerror(ret)); + return 1; + } + for(p = result; p != NULL; p = p->ai_next) + { + sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (sockfd == INVALID_SOCKET) { continue; } + if (connect(sockfd, p->ai_addr, p->ai_addrlen) != SOCKET_ERROR) { + break; + } + closesocket(sockfd); + sockfd = INVALID_SOCKET; + } + freeaddrinfo(result); + return sockfd; +} + + +class _DummyWebSocket : public easywsclient::WebSocket +{ + public: + void poll(int timeout) { } + void send(const std::string& message) { } + void sendBinary(const std::string& message) { } + void sendBinary(const std::vector& message) { } + void sendPing() { } + void close() { } + readyStateValues getReadyState() const { return CLOSED; } + void _dispatch(Callback_Imp & callable) { } + void _dispatchBinary(BytesCallback_Imp& callable) { } +}; + + +class _RealWebSocket : public easywsclient::WebSocket +{ + public: + // http://tools.ietf.org/html/rfc6455#section-5.2 Base Framing Protocol + // + // 0 1 2 3 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + // +-+-+-+-+-------+-+-------------+-------------------------------+ + // |F|R|R|R| opcode|M| Payload len | Extended payload length | + // |I|S|S|S| (4) |A| (7) | (16/64) | + // |N|V|V|V| |S| | (if payload len==126/127) | + // | |1|2|3| |K| | | + // +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + + // | Extended payload length continued, if payload len == 127 | + // + - - - - - - - - - - - - - - - +-------------------------------+ + // | |Masking-key, if MASK set to 1 | + // +-------------------------------+-------------------------------+ + // | Masking-key (continued) | Payload Data | + // +-------------------------------- - - - - - - - - - - - - - - - + + // : Payload Data continued ... : + // + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + // | Payload Data continued ... | + // +---------------------------------------------------------------+ + struct wsheader_type { + unsigned header_size; + bool fin; + bool mask; + enum opcode_type { + CONTINUATION = 0x0, + TEXT_FRAME = 0x1, + BINARY_FRAME = 0x2, + CLOSE = 8, + PING = 9, + PONG = 0xa, + } opcode; + int N0; + uint64_t N; + uint8_t masking_key[4]; + }; + + std::vector rxbuf; + std::vector txbuf; + std::vector receivedData; + + socket_t sockfd; + readyStateValues readyState; + bool useMask; + + _RealWebSocket(socket_t sockfd, bool useMask) : sockfd(sockfd), readyState(OPEN), useMask(useMask) { + } + + readyStateValues getReadyState() const { + return readyState; + } + + void poll(int timeout) { // timeout in milliseconds + if (readyState == CLOSED) { + if (timeout > 0) { + timeval tv = { timeout/1000, (timeout%1000) * 1000 }; + select(0, NULL, NULL, NULL, &tv); + } + return; + } + if (timeout != 0) { + fd_set rfds; + fd_set wfds; + timeval tv = { timeout/1000, (timeout%1000) * 1000 }; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_SET(sockfd, &rfds); + if (txbuf.size()) { FD_SET(sockfd, &wfds); } + select(sockfd + 1, &rfds, &wfds, 0, timeout > 0 ? &tv : 0); + } + while (true) { + // FD_ISSET(0, &rfds) will be true + int N = rxbuf.size(); + ssize_t ret; + rxbuf.resize(N + 1500); + ret = recv(sockfd, (char*)&rxbuf[0] + N, 1500, 0); + if (false) { } + else if (ret < 0 && (socketerrno == SOCKET_EWOULDBLOCK || socketerrno == SOCKET_EAGAIN_EINPROGRESS)) { + rxbuf.resize(N); + break; + } + else if (ret <= 0) { + rxbuf.resize(N); + closesocket(sockfd); + readyState = CLOSED; + fputs(ret < 0 ? "Connection error!\n" : "Connection closed!\n", stderr); + break; + } + else { + rxbuf.resize(N + ret); + } + } + while (txbuf.size()) { + int ret = ::send(sockfd, (char*)&txbuf[0], txbuf.size(), 0); + if (false) { } // ?? + else if (ret < 0 && (socketerrno == SOCKET_EWOULDBLOCK || socketerrno == SOCKET_EAGAIN_EINPROGRESS)) { + break; + } + else if (ret <= 0) { + closesocket(sockfd); + readyState = CLOSED; + fputs(ret < 0 ? "Connection error!\n" : "Connection closed!\n", stderr); + break; + } + else { + txbuf.erase(txbuf.begin(), txbuf.begin() + ret); + } + } + if (!txbuf.size() && readyState == CLOSING) { + closesocket(sockfd); + readyState = CLOSED; + } + } + + // Callable must have signature: void(const std::string & message). + // Should work with C functions, C++ functors, and C++11 std::function and + // lambda: + //template + //void dispatch(Callable callable) + virtual void _dispatch(Callback_Imp & callable) { + struct CallbackAdapter : public BytesCallback_Imp + // Adapt void(const std::string&) to void(const std::string&) + { + Callback_Imp& callable; + CallbackAdapter(Callback_Imp& callable) : callable(callable) { } + void operator()(const std::vector& message) { + std::string stringMessage(message.begin(), message.end()); + callable(stringMessage); + } + }; + CallbackAdapter bytesCallback(callable); + _dispatchBinary(bytesCallback); + } + + virtual void _dispatchBinary(BytesCallback_Imp & callable) { + // TODO: consider acquiring a lock on rxbuf... + while (true) { + wsheader_type ws; + if (rxbuf.size() < 2) { return; /* Need at least 2 */ } + const uint8_t * data = (uint8_t *) &rxbuf[0]; // peek, but don't consume + ws.fin = (data[0] & 0x80) == 0x80; + ws.opcode = (wsheader_type::opcode_type) (data[0] & 0x0f); + ws.mask = (data[1] & 0x80) == 0x80; + ws.N0 = (data[1] & 0x7f); + ws.header_size = 2 + (ws.N0 == 126? 2 : 0) + (ws.N0 == 127? 8 : 0) + (ws.mask? 4 : 0); + if (rxbuf.size() < ws.header_size) { return; /* Need: ws.header_size - rxbuf.size() */ } + int i = 0; + if (ws.N0 < 126) { + ws.N = ws.N0; + i = 2; + } + else if (ws.N0 == 126) { + ws.N = 0; + ws.N |= ((uint64_t) data[2]) << 8; + ws.N |= ((uint64_t) data[3]) << 0; + i = 4; + } + else if (ws.N0 == 127) { + ws.N = 0; + ws.N |= ((uint64_t) data[2]) << 56; + ws.N |= ((uint64_t) data[3]) << 48; + ws.N |= ((uint64_t) data[4]) << 40; + ws.N |= ((uint64_t) data[5]) << 32; + ws.N |= ((uint64_t) data[6]) << 24; + ws.N |= ((uint64_t) data[7]) << 16; + ws.N |= ((uint64_t) data[8]) << 8; + ws.N |= ((uint64_t) data[9]) << 0; + i = 10; + } + if (ws.mask) { + ws.masking_key[0] = ((uint8_t) data[i+0]) << 0; + ws.masking_key[1] = ((uint8_t) data[i+1]) << 0; + ws.masking_key[2] = ((uint8_t) data[i+2]) << 0; + ws.masking_key[3] = ((uint8_t) data[i+3]) << 0; + } + else { + ws.masking_key[0] = 0; + ws.masking_key[1] = 0; + ws.masking_key[2] = 0; + ws.masking_key[3] = 0; + } + if (rxbuf.size() < ws.header_size+ws.N) { return; /* Need: ws.header_size+ws.N - rxbuf.size() */ } + + // We got a whole message, now do something with it: + if (false) { } + else if ( + ws.opcode == wsheader_type::TEXT_FRAME + || ws.opcode == wsheader_type::BINARY_FRAME + || ws.opcode == wsheader_type::CONTINUATION + ) { + if (ws.mask) { for (size_t i = 0; i != ws.N; ++i) { rxbuf[i+ws.header_size] ^= ws.masking_key[i&0x3]; } } + receivedData.insert(receivedData.end(), rxbuf.begin()+ws.header_size, rxbuf.begin()+ws.header_size+(size_t)ws.N);// just feed + if (ws.fin) { + callable((const std::vector) receivedData); + receivedData.erase(receivedData.begin(), receivedData.end()); + std::vector ().swap(receivedData);// free memory + } + } + else if (ws.opcode == wsheader_type::PING) { + if (ws.mask) { for (size_t i = 0; i != ws.N; ++i) { rxbuf[i+ws.header_size] ^= ws.masking_key[i&0x3]; } } + std::string data(rxbuf.begin()+ws.header_size, rxbuf.begin()+ws.header_size+(size_t)ws.N); + sendData(wsheader_type::PONG, data.size(), data.begin(), data.end()); + } + else if (ws.opcode == wsheader_type::PONG) { } + else if (ws.opcode == wsheader_type::CLOSE) { close(); } + else { vLog(LOG_ERROR, "ERROR: Got unexpected WebSocket message.\n"); close(); } + + rxbuf.erase(rxbuf.begin(), rxbuf.begin() + ws.header_size+(size_t)ws.N); + } + } + + void sendPing() { + std::string empty; + sendData(wsheader_type::PING, empty.size(), empty.begin(), empty.end()); + } + + void send(const std::string& message) { + sendData(wsheader_type::TEXT_FRAME, message.size(), message.begin(), message.end()); + } + + void sendBinary(const std::string& message) { + sendData(wsheader_type::BINARY_FRAME, message.size(), message.begin(), message.end()); + } + + void sendBinary(const std::vector& message) { + sendData(wsheader_type::BINARY_FRAME, message.size(), message.begin(), message.end()); + } + + template + void sendData(wsheader_type::opcode_type type, uint64_t message_size, Iterator message_begin, Iterator message_end) { + // TODO: + // Masking key should (must) be derived from a high quality random + // number generator, to mitigate attacks on non-WebSocket friendly + // middleware: + const uint8_t masking_key[4] = { 0x12, 0x34, 0x56, 0x78 }; + // TODO: consider acquiring a lock on txbuf... + if (readyState == CLOSING || readyState == CLOSED) { return; } + std::vector header; + header.assign(2 + (message_size >= 126 ? 2 : 0) + (message_size >= 65536 ? 6 : 0) + (useMask ? 4 : 0), 0); + header[0] = 0x80 | type; + if (false) { } + else if (message_size < 126) { + header[1] = (message_size & 0xff) | (useMask ? 0x80 : 0); + if (useMask) { + header[2] = masking_key[0]; + header[3] = masking_key[1]; + header[4] = masking_key[2]; + header[5] = masking_key[3]; + } + } + else if (message_size < 65536) { + header[1] = 126 | (useMask ? 0x80 : 0); + header[2] = (message_size >> 8) & 0xff; + header[3] = (message_size >> 0) & 0xff; + if (useMask) { + header[4] = masking_key[0]; + header[5] = masking_key[1]; + header[6] = masking_key[2]; + header[7] = masking_key[3]; + } + } + else { // TODO: run coverage testing here + header[1] = 127 | (useMask ? 0x80 : 0); + header[2] = (message_size >> 56) & 0xff; + header[3] = (message_size >> 48) & 0xff; + header[4] = (message_size >> 40) & 0xff; + header[5] = (message_size >> 32) & 0xff; + header[6] = (message_size >> 24) & 0xff; + header[7] = (message_size >> 16) & 0xff; + header[8] = (message_size >> 8) & 0xff; + header[9] = (message_size >> 0) & 0xff; + if (useMask) { + header[10] = masking_key[0]; + header[11] = masking_key[1]; + header[12] = masking_key[2]; + header[13] = masking_key[3]; + } + } + // N.B. - txbuf will keep growing until it can be transmitted over the socket: + txbuf.insert(txbuf.end(), header.begin(), header.end()); + txbuf.insert(txbuf.end(), message_begin, message_end); + if (useMask) { + for (size_t i = 0; i != message_size; ++i) { *(txbuf.end() - message_size + i) ^= masking_key[i&0x3]; } + } + } + + void close() { + if(readyState == CLOSING || readyState == CLOSED) { return; } + readyState = CLOSING; + uint8_t closeFrame[6] = {0x88, 0x80, 0x00, 0x00, 0x00, 0x00}; // last 4 bytes are a masking key + std::vector header(closeFrame, closeFrame+6); + txbuf.insert(txbuf.end(), header.begin(), header.end()); + } + +}; + + +easywsclient::WebSocket::pointer from_url(const std::string& url, bool useMask, const std::string& origin) { + char host[128]; + int port; + char path[128]; + if (url.size() >= 128) { + vLog(LOG_ERROR, "ERROR: url size limit exceeded: %s\n", url.c_str()); + return NULL; + } + if (origin.size() >= 200) { + vLog(LOG_ERROR, "ERROR: origin size limit exceeded: %s\n", origin.c_str()); + return NULL; + } + if (false) { } + else if (sscanf(url.c_str(), "ws://%[^:/]:%d/%s", host, &port, path) == 3) { + } + else if (sscanf(url.c_str(), "ws://%[^:/]/%s", host, path) == 2) { + port = 80; + } + else if (sscanf(url.c_str(), "ws://%[^:/]:%d", host, &port) == 2) { + path[0] = '\0'; + } + else if (sscanf(url.c_str(), "ws://%[^:/]", host) == 1) { + port = 80; + path[0] = '\0'; + } + else { + vLog(LOG_ERROR, "ERROR: Could not parse WebSocket url: %s\n", url.c_str()); + return NULL; + } + vLog(LOG_DEBUG, "easywsclient: connecting: host=%s port=%d path=/%s\n", host, port, path); + socket_t sockfd = hostname_connect(host, port); + if (sockfd == INVALID_SOCKET) { + vLog(LOG_ERROR, "Unable to connect to %s:%d\n", host, port); + return NULL; + } + { + // XXX: this should be done non-blocking, + char line[256]; + int status; + int i; + snprintf(line, 256, "GET /%s HTTP/1.1\r\n", path); ::send(sockfd, line, strlen(line), 0); + if (port == 80) { + snprintf(line, 256, "Host: %s\r\n", host); ::send(sockfd, line, strlen(line), 0); + } + else { + snprintf(line, 256, "Host: %s:%d\r\n", host, port); ::send(sockfd, line, strlen(line), 0); + } + snprintf(line, 256, "Upgrade: websocket\r\n"); ::send(sockfd, line, strlen(line), 0); + snprintf(line, 256, "Connection: Upgrade\r\n"); ::send(sockfd, line, strlen(line), 0); + if (!origin.empty()) { + snprintf(line, 256, "Origin: %s\r\n", origin.c_str()); ::send(sockfd, line, strlen(line), 0); + } + snprintf(line, 256, "Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n"); ::send(sockfd, line, strlen(line), 0); + snprintf(line, 256, "Sec-WebSocket-Version: 13\r\n"); ::send(sockfd, line, strlen(line), 0); + snprintf(line, 256, "\r\n"); ::send(sockfd, line, strlen(line), 0); + for (i = 0; i < 2 || (i < 255 && line[i-2] != '\r' && line[i-1] != '\n'); ++i) { if (recv(sockfd, line+i, 1, 0) == 0) { return NULL; } } + line[i] = 0; + if (i == 255) { vLog(LOG_ERROR, "ERROR: Got invalid status line connecting to: %s\n", url.c_str()); return NULL; } + if (sscanf(line, "HTTP/1.1 %d", &status) != 1 || status != 101) { vLog(LOG_ERROR, "ERROR: Got bad status connecting to %s: %s", url.c_str(), line); return NULL; } + // TODO: verify response headers, + while (true) { + for (i = 0; i < 2 || (i < 255 && line[i-2] != '\r' && line[i-1] != '\n'); ++i) { if (recv(sockfd, line+i, 1, 0) == 0) { return NULL; } } + if (line[0] == '\r' && line[1] == '\n') { break; } + } + } + int flag = 1; + setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof(flag)); // Disable Nagle's algorithm +#ifdef _WIN32 + u_long on = 1; + ioctlsocket(sockfd, FIONBIO, &on); +#else + fcntl(sockfd, F_SETFL, O_NONBLOCK); +#endif + vLog(LOG_DEBUG, "Connected to: %s\n", url.c_str()); + return easywsclient::WebSocket::pointer(new _RealWebSocket(sockfd, useMask)); +} + +} // end of module-only namespace + + + +namespace easywsclient { + +WebSocket::pointer WebSocket::create_dummy() { + static pointer dummy = pointer(new _DummyWebSocket); + return dummy; +} + + +WebSocket::pointer WebSocket::from_url(const std::string& url, const std::string& origin) { + return ::from_url(url, true, origin); +} + +WebSocket::pointer WebSocket::from_url_no_mask(const std::string& url, const std::string& origin) { + return ::from_url(url, false, origin); +} + + +} // namespace easywsclient diff --git a/ui/dasadmin/src/views/backend/home/windMatrix.vue b/ui/dasadmin/src/views/backend/home/windMatrix.vue index 88f483b6..51e1d763 100644 --- a/ui/dasadmin/src/views/backend/home/windMatrix.vue +++ b/ui/dasadmin/src/views/backend/home/windMatrix.vue @@ -90,7 +90,7 @@ const props = defineProps({ const getAnimationStyle = (item) => { const irotorspeed = item.attributeMap?.irotorspeed ?? 0 let animationDuration; - if(irotorspeed>15){ + if(irotorspeed>10){ animationDuration= 60 / irotorspeed }else{ animationDuration = 60 / irotorspeed / 5