we7.cc常用方法_url()

  • url() - 创建一个URL
url($segment, $params = array(), $noredirect = false);
>>>eg:
    echo url('site/entry/themeset', array('m' => 'we7_demo'));
    //http://we7.cc/web/index.php?c=site&a=entry&do=themeset&m=we7_demo

路由的表达式以斜杠“/”的方式组织,每个以斜杠分隔的片段都是指向某一控制器(controller)、操作(action)或是行为(do)。第二个参数则是以数组的形式表示URL中的QueryString。
/* ESP HTTP Client Example This example code is in the Public Domain (or CC0 licensed, at your option.) Unless required by applicable law or agreed to in writing, this software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ #include <string.h> #include <sys/param.h> #include <stdlib.h> #include <ctype.h> #include "esp_log.h" #include "nvs_flash.h" #include "esp_event.h" #include "esp_netif.h" #include "protocol_examples_common.h" #include "protocol_examples_utils.h" #include "esp_tls.h" #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE #include "esp_crt_bundle.h" #endif #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "esp_http_client.h" #define MAX_HTTP_RECV_BUFFER 512 #define MAX_HTTP_OUTPUT_BUFFER 2048 static const char *TAG = "HTTP_CLIENT"; /* Root cert for howsmyssl.com, taken from howsmyssl_com_root_cert.pem The PEM file was extracted from the output of this command: openssl s_client -showcerts -connect www.howsmyssl.com:443 </dev/null The CA root cert is the last cert given in the chain of certs. To embed it in the app binary, the PEM file is named in the component.mk COMPONENT_EMBED_TXTFILES variable. */ extern const char howsmyssl_com_root_cert_pem_start[] asm("_binary_howsmyssl_com_root_cert_pem_start"); extern const char howsmyssl_com_root_cert_pem_end[] asm("_binary_howsmyssl_com_root_cert_pem_end"); esp_err_t _http_event_handler(esp_http_client_event_t *evt) { static char *output_buffer; // Buffer to store response of http request from event handler static int output_len; // Stores number of bytes read switch(evt->event_id) { case HTTP_EVENT_ERROR: ESP_LOGD(TAG, "HTTP_EVENT_ERROR"); break; case HTTP_EVENT_ON_CONNECTED: ESP_LOGD(TAG, "HTTP_EVENT_ON_CONNECTED"); break; case HTTP_EVENT_HEADER_SENT: ESP_LOGD(TAG, "HTTP_EVENT_HEADER_SENT"); break; case HTTP_EVENT_ON_HEADER: ESP_LOGD(TAG, "HTTP_EVENT_ON_HEADER, key=%s, value=%s", evt->header_key, evt->header_value); break; case HTTP_EVENT_ON_DATA: ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len); // Clean the buffer in case of a new request if (output_len == 0 && evt->user_data) { // we are just starting to copy the output data into the use memset(evt->user_data, 0, MAX_HTTP_OUTPUT_BUFFER); } /* * Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data. * However, event handler can also be used in case chunked encoding is used. */ if (!esp_http_client_is_chunked_response(evt->client)) { // If user_data buffer is configured, copy the response into the buffer int copy_len = 0; if (evt->user_data) { // The last byte in evt->user_data is kept for the NULL character in case of out-of-bound access. copy_len = MIN(evt->data_len, (MAX_HTTP_OUTPUT_BUFFER - output_len)); if (copy_len) { memcpy(evt->user_data + output_len, evt->data, copy_len); } } else { int content_len = esp_http_client_get_content_length(evt->client); if (output_buffer == NULL) { // We initialize output_buffer with 0 because it is used by strlen() and similar functions therefore should be null terminated. output_buffer = (char *) calloc(content_len + 1, sizeof(char)); output_len = 0; if (output_buffer == NULL) { ESP_LOGE(TAG, "Failed to allocate memory for output buffer"); return ESP_FAIL; } } copy_len = MIN(evt->data_len, (content_len - output_len)); if (copy_len) { memcpy(output_buffer + output_len, evt->data, copy_len); } } output_len += copy_len; } break; case HTTP_EVENT_ON_FINISH: ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH"); if (output_buffer != NULL) { #if CONFIG_EXAMPLE_ENABLE_RESPONSE_BUFFER_DUMP ESP_LOG_BUFFER_HEX(TAG, output_buffer, output_len); #endif free(output_buffer); output_buffer = NULL; } output_len = 0; break; case HTTP_EVENT_DISCONNECTED: ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED"); int mbedtls_err = 0; esp_err_t err = esp_tls_get_and_clear_last_error((esp_tls_error_handle_t)evt->data, &mbedtls_err, NULL); if (err != 0) { ESP_LOGI(TAG, "Last esp error code: 0x%x", err); ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err); } if (output_buffer != NULL) { free(output_buffer); output_buffer = NULL; } output_len = 0; break; case HTTP_EVENT_REDIRECT: ESP_LOGD(TAG, "HTTP_EVENT_REDIRECT"); esp_http_client_set_header(evt->client, "From", "user@example.com"); esp_http_client_set_header(evt->client, "Accept", "text/html"); esp_http_client_set_redirection(evt->client); break; } return ESP_OK; } static void http_rest_with_url(void) { // Declare local_response_buffer with size (MAX_HTTP_OUTPUT_BUFFER + 1) to prevent out of bound access when // it is used by functions like strlen(). The buffer should only be used upto size MAX_HTTP_OUTPUT_BUFFER char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER + 1] = {0}; /** * NOTE: All the configuration parameters for http_client must be specified either in URL or as host and path parameters. * If host and path parameters are not set, query parameter will be ignored. In such cases, * query parameter should be specified in URL. * * If URL as well as host and path parameters are specified, values of host and path will be considered. */ esp_http_client_config_t config = { .host = CONFIG_EXAMPLE_HTTP_ENDPOINT, .path = "/get", .query = "esp", .event_handler = _http_event_handler, .user_data = local_response_buffer, // Pass address of local buffer to get response .disable_auto_redirect = true, }; ESP_LOGI(TAG, "HTTP request with url =>"); esp_http_client_handle_t client = esp_http_client_init(&config); // GET esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err)); } ESP_LOG_BUFFER_HEX(TAG, local_response_buffer, strlen(local_response_buffer)); // POST const char *post_data = "{\"field1\":\"value1\"}"; esp_http_client_set_url(client, "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/post"); esp_http_client_set_method(client, HTTP_METHOD_POST); esp_http_client_set_header(client, "Content-Type", "application/json"); esp_http_client_set_post_field(client, post_data, strlen(post_data)); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err)); } //PUT esp_http_client_set_url(client, "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/put"); esp_http_client_set_method(client, HTTP_METHOD_PUT); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP PUT request failed: %s", esp_err_to_name(err)); } //PATCH esp_http_client_set_url(client, "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/patch"); esp_http_client_set_method(client, HTTP_METHOD_PATCH); esp_http_client_set_post_field(client, NULL, 0); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP PATCH Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP PATCH request failed: %s", esp_err_to_name(err)); } //DELETE esp_http_client_set_url(client, "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/delete"); esp_http_client_set_method(client, HTTP_METHOD_DELETE); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP DELETE Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP DELETE request failed: %s", esp_err_to_name(err)); } //HEAD esp_http_client_set_url(client, "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/get"); esp_http_client_set_method(client, HTTP_METHOD_HEAD); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP HEAD Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP HEAD request failed: %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } static void http_rest_with_hostname_path(void) { esp_http_client_config_t config = { .host = CONFIG_EXAMPLE_HTTP_ENDPOINT, .path = "/get", .transport_type = HTTP_TRANSPORT_OVER_TCP, .event_handler = _http_event_handler, }; ESP_LOGI(TAG, "HTTP request with hostname and path =>"); esp_http_client_handle_t client = esp_http_client_init(&config); // GET esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err)); } // POST const char *post_data = "field1=value1&field2=value2"; esp_http_client_set_url(client, "/post"); esp_http_client_set_method(client, HTTP_METHOD_POST); esp_http_client_set_post_field(client, post_data, strlen(post_data)); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err)); } //PUT esp_http_client_set_url(client, "/put"); esp_http_client_set_method(client, HTTP_METHOD_PUT); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP PUT request failed: %s", esp_err_to_name(err)); } //PATCH esp_http_client_set_url(client, "/patch"); esp_http_client_set_method(client, HTTP_METHOD_PATCH); esp_http_client_set_post_field(client, NULL, 0); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP PATCH Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP PATCH request failed: %s", esp_err_to_name(err)); } //DELETE esp_http_client_set_url(client, "/delete"); esp_http_client_set_method(client, HTTP_METHOD_DELETE); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP DELETE Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP DELETE request failed: %s", esp_err_to_name(err)); } //HEAD esp_http_client_set_url(client, "/get"); esp_http_client_set_method(client, HTTP_METHOD_HEAD); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP HEAD Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP HEAD request failed: %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } #if CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH static void http_auth_basic(void) { /** * Note: `max_authorization_retries` in esp_http_client_config_t * can be used to configure number of retry attempts to be performed * in case unauthorized status code is received. * * To disable authorization retries, set max_authorization_retries to -1. */ esp_http_client_config_t config = { .url = "http://user:passwd@"CONFIG_EXAMPLE_HTTP_ENDPOINT"/basic-auth/user/passwd", .event_handler = _http_event_handler, .auth_type = HTTP_AUTH_TYPE_BASIC, .max_authorization_retries = -1, }; ESP_LOGI(TAG, "HTTP Basic Auth request =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP Basic Auth Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } static void http_auth_basic_redirect(void) { esp_http_client_config_t config = { .url = "http://user:passwd@"CONFIG_EXAMPLE_HTTP_ENDPOINT"/basic-auth/user/passwd", .event_handler = _http_event_handler, }; ESP_LOGI(TAG, "HTTP Basic Auth redirect request =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP Basic Auth redirect Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } #endif #if CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH static void http_auth_digest_md5(void) { esp_http_client_config_t config = { .url = "http://user:passwd@"CONFIG_EXAMPLE_HTTP_ENDPOINT"/digest-auth/auth/user/passwd/MD5/never", .event_handler = _http_event_handler, }; ESP_LOGI(TAG, "HTTP MD5 Digest Auth request =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP MD5 Digest Auth Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error performing http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } static void http_auth_digest_sha256(void) { esp_http_client_config_t config = { .url = "http://user:passwd@"CONFIG_EXAMPLE_HTTP_ENDPOINT"/digest-auth/auth/user/passwd/SHA-256/never", .event_handler = _http_event_handler, .buffer_size_tx = 1024, // Increase buffer size as header size will increase as it contains SHA-256. }; ESP_LOGI(TAG, "HTTP SHA256 Digest Auth request =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP SHA256 Digest Auth Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error performing http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } #endif #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE static void https_with_url(void) { esp_http_client_config_t config = { .url = "https://www.howsmyssl.com", .event_handler = _http_event_handler, .crt_bundle_attach = esp_crt_bundle_attach, }; ESP_LOGI(TAG, "HTTPS request with url =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } #endif // CONFIG_MBEDTLS_CERTIFICATE_BUNDLE static void https_with_hostname_path(void) { esp_http_client_config_t config = { .host = "www.howsmyssl.com", .path = "/", .transport_type = HTTP_TRANSPORT_OVER_SSL, .event_handler = _http_event_handler, .cert_pem = howsmyssl_com_root_cert_pem_start, }; ESP_LOGI(TAG, "HTTPS request with hostname and path =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } static void http_encoded_query(void) { esp_http_client_config_t config = { .host = CONFIG_EXAMPLE_HTTP_ENDPOINT, .path = "/get", .event_handler = _http_event_handler, }; ESP_LOGI(TAG, "HTTP GET request with encoded query =>"); static const char query_val[] = "ABC xyz!012@#%&"; char query_val_enc[64] = {0}; uint32_t enc_len = example_uri_encode(query_val_enc, query_val, strlen(query_val)); if (enc_len > 0) { ESP_LOG_BUFFER_HEXDUMP(TAG, query_val_enc, enc_len, ESP_LOG_DEBUG); config.query = query_val_enc; } esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err)); } } static void http_relative_redirect(void) { esp_http_client_config_t config = { .url = "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/relative-redirect/3", .event_handler = _http_event_handler, }; ESP_LOGI(TAG, "HTTP Relative path redirect request =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP Relative path redirect Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } static void http_absolute_redirect(void) { esp_http_client_config_t config = { .url = "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/absolute-redirect/3", .event_handler = _http_event_handler, }; ESP_LOGI(TAG, "HTTP Absolute path redirect request =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP Absolute path redirect Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } static void http_absolute_redirect_manual(void) { esp_http_client_config_t config = { .url = "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/absolute-redirect/3", .event_handler = _http_event_handler, .disable_auto_redirect = true, }; ESP_LOGI(TAG, "HTTP Absolute path redirect (manual) request =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP Absolute path redirect (manual) Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } static void http_redirect_to_https(void) { esp_http_client_config_t config = { .url = "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/redirect-to?url=https://www.howsmyssl.com", .event_handler = _http_event_handler, .cert_pem = howsmyssl_com_root_cert_pem_start, }; ESP_LOGI(TAG, "HTTP redirect to HTTPS request =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP redirect to HTTPS Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } static void http_download_chunk(void) { esp_http_client_config_t config = { .url = "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/stream-bytes/8912", .event_handler = _http_event_handler, }; ESP_LOGI(TAG, "HTTP chunk encoding request =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP chunk encoding Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } static void http_perform_as_stream_reader(void) { char *buffer = malloc(MAX_HTTP_RECV_BUFFER + 1); if (buffer == NULL) { ESP_LOGE(TAG, "Cannot malloc http receive buffer"); return; } esp_http_client_config_t config = { .url = "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/get", }; ESP_LOGI(TAG, "HTTP Stream reader request =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err; if ((err = esp_http_client_open(client, 0)) != ESP_OK) { ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err)); free(buffer); return; } int content_length = esp_http_client_fetch_headers(client); int total_read_len = 0, read_len; if (total_read_len < content_length && content_length <= MAX_HTTP_RECV_BUFFER) { read_len = esp_http_client_read(client, buffer, content_length); if (read_len <= 0) { ESP_LOGE(TAG, "Error read data"); } buffer[read_len] = 0; ESP_LOGD(TAG, "read_len = %d", read_len); } ESP_LOGI(TAG, "HTTP Stream reader Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); esp_http_client_close(client); esp_http_client_cleanup(client); free(buffer); } static void https_async(void) { esp_http_client_config_t config = { .url = "https://postman-echo.com/post", .event_handler = _http_event_handler, .crt_bundle_attach = esp_crt_bundle_attach, .is_async = true, .timeout_ms = 5000, }; ESP_LOGI(TAG, "HTTPS async requests =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err; const char *post_data = "Using a Palantír requires a person with great strength of will and wisdom. The Palantíri were meant to " "be used by the Dúnedain to communicate throughout the Realms in Exile. During the War of the Ring, " "the Palantíri were used by many individuals. Sauron used the Ithil-stone to take advantage of the users " "of the other two stones, the Orthanc-stone and Anor-stone, but was also susceptible to deception himself."; esp_http_client_set_method(client, HTTP_METHOD_POST); esp_http_client_set_post_field(client, post_data, strlen(post_data)); while (1) { err = esp_http_client_perform(client); if (err != ESP_ERR_HTTP_EAGAIN) { break; } } if (err == ESP_OK) { ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); // Test HTTP_METHOD_HEAD with is_async enabled config.url = "https://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/get"; config.event_handler = _http_event_handler; config.crt_bundle_attach = esp_crt_bundle_attach; config.is_async = true; config.timeout_ms = 5000; client = esp_http_client_init(&config); esp_http_client_set_method(client, HTTP_METHOD_HEAD); while (1) { err = esp_http_client_perform(client); if (err != ESP_ERR_HTTP_EAGAIN) { break; } } if (err == ESP_OK) { ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } static void https_with_invalid_url(void) { esp_http_client_config_t config = { .url = "https://not.existent.url", .event_handler = _http_event_handler, }; ESP_LOGI(TAG, "HTTPS request with invalid url =>"); esp_http_client_handle_t client = esp_http_client_init(&config); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } /* * http_native_request() demonstrates use of low level APIs to connect to a server, * make a http request and read response. Event handler is not used in this case. * Note: This approach should only be used in case use of low level APIs is required. * The easiest way is to use esp_http_perform() */ static void http_native_request(void) { // Declare local_response_buffer with size (MAX_HTTP_OUTPUT_BUFFER + 1) to prevent out of bound access when // it is used by functions like strlen(). The buffer should only be used upto size MAX_HTTP_OUTPUT_BUFFER char output_buffer[MAX_HTTP_OUTPUT_BUFFER + 1] = {0}; // Buffer to store response of http request int content_length = 0; esp_http_client_config_t config = { .url = "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/get", }; ESP_LOGI(TAG, "HTTP native request =>"); esp_http_client_handle_t client = esp_http_client_init(&config); // GET Request esp_http_client_set_method(client, HTTP_METHOD_GET); esp_err_t err = esp_http_client_open(client, 0); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err)); } else { content_length = esp_http_client_fetch_headers(client); if (content_length < 0) { ESP_LOGE(TAG, "HTTP client fetch headers failed"); } else { int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER); if (data_read >= 0) { ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); ESP_LOG_BUFFER_HEX(TAG, output_buffer, data_read); } else { ESP_LOGE(TAG, "Failed to read response"); } } } esp_http_client_close(client); // POST Request const char *post_data = "{\"field1\":\"value1\"}"; esp_http_client_set_url(client, "http://"CONFIG_EXAMPLE_HTTP_ENDPOINT"/post"); esp_http_client_set_method(client, HTTP_METHOD_POST); esp_http_client_set_header(client, "Content-Type", "application/json"); err = esp_http_client_open(client, strlen(post_data)); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err)); } else { int wlen = esp_http_client_write(client, post_data, strlen(post_data)); if (wlen < 0) { ESP_LOGE(TAG, "Write failed"); } content_length = esp_http_client_fetch_headers(client); if (content_length < 0) { ESP_LOGE(TAG, "HTTP client fetch headers failed"); } else { int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER); if (data_read >= 0) { ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); ESP_LOG_BUFFER_HEX(TAG, output_buffer, strlen(output_buffer)); } else { ESP_LOGE(TAG, "Failed to read response"); } } } esp_http_client_cleanup(client); } #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE static void http_partial_download(void) { esp_http_client_config_t config = { .url = "https://dl.espressif.com/dl/esp-idf/ci/esp_http_client_demo.txt", .event_handler = _http_event_handler, .crt_bundle_attach = esp_crt_bundle_attach, }; ESP_LOGI(TAG, "HTTP partial download =>"); esp_http_client_handle_t client = esp_http_client_init(&config); // Download a file excluding first 10 bytes esp_http_client_set_header(client, "Range", "bytes=10-"); esp_err_t err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err)); } // Download last 10 bytes of a file esp_http_client_set_header(client, "Range", "bytes=-10"); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err)); } // Download 10 bytes from 11 to 20 esp_http_client_set_header(client, "Range", "bytes=11-20"); err = esp_http_client_perform(client); if (err == ESP_OK) { ESP_LOGI(TAG, "HTTP Status = %d, content_length = %"PRId64, esp_http_client_get_status_code(client), esp_http_client_get_content_length(client)); } else { ESP_LOGE(TAG, "HTTP request failed: %s", esp_err_to_name(err)); } esp_http_client_cleanup(client); } #endif // CONFIG_MBEDTLS_CERTIFICATE_BUNDLE static void http_test_task(void *pvParameters) { http_rest_with_url(); http_rest_with_hostname_path(); #if CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH http_auth_basic(); http_auth_basic_redirect(); #endif #if CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH http_auth_digest_md5(); http_auth_digest_sha256(); #endif http_encoded_query(); http_relative_redirect(); http_absolute_redirect(); http_absolute_redirect_manual(); #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE https_with_url(); #endif https_with_hostname_path(); http_redirect_to_https(); http_download_chunk(); http_perform_as_stream_reader(); https_async(); https_with_invalid_url(); http_native_request(); #if CONFIG_MBEDTLS_CERTIFICATE_BUNDLE http_partial_download(); #endif ESP_LOGI(TAG, "Finish http example"); #if !CONFIG_IDF_TARGET_LINUX vTaskDelete(NULL); #endif } void app_main(void) { esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. * Read "Establishing Wi-Fi or Ethernet Connection" section in * examples/protocols/README.md for more information about this function. */ ESP_ERROR_CHECK(example_connect()); ESP_LOGI(TAG, "Connected to AP, begin http example"); #if CONFIG_IDF_TARGET_LINUX http_test_task(NULL); #else xTaskCreate(&http_test_task, "http_test_task", 8192, NULL, 5, NULL); #endif }解析该代码
最新发布
11-01
分析代码:################################################################################ # # Linux kernel target # ################################################################################ LINUX_VERSION = $(call qstrip,$(BR2_LINUX_KERNEL_VERSION)) LINUX_LICENSE = GPLv2 LINUX_LICENSE_FILES = COPYING # Compute LINUX_SOURCE and LINUX_SITE from the configuration ifeq ($(BR2_LINUX_KERNEL_CUSTOM_TARBALL),y) LINUX_TARBALL = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_TARBALL_LOCATION)) LINUX_SITE = $(patsubst %/,%,$(dir $(LINUX_TARBALL))) LINUX_SOURCE = $(notdir $(LINUX_TARBALL)) BR_NO_CHECK_HASH_FOR += $(LINUX_SOURCE) else ifeq ($(BR2_LINUX_KERNEL_CUSTOM_LOCAL),y) LINUX_SITE = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_LOCAL_PATH)) LINUX_SITE_METHOD = local else ifeq ($(BR2_LINUX_KERNEL_CUSTOM_GIT),y) LINUX_SITE = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_REPO_URL)) LINUX_SITE_METHOD = git else ifeq ($(BR2_LINUX_KERNEL_CUSTOM_HG),y) LINUX_SITE = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_REPO_URL)) LINUX_SITE_METHOD = hg else LINUX_SOURCE = linux-$(LINUX_VERSION).tar.xz ifeq ($(BR2_LINUX_KERNEL_CUSTOM_VERSION),y) BR_NO_CHECK_HASH_FOR += $(LINUX_SOURCE) endif ifeq ($(BR2_LINUX_KERNEL_SAME_AS_HEADERS)$(BR2_KERNEL_HEADERS_VERSION),yy) BR_NO_CHECK_HASH_FOR += $(LINUX_SOURCE) endif # In X.Y.Z, get X and Y. We replace dots and dashes by spaces in order # to use the $(word) function. We support versions such as 4.0, 3.1, # 2.6.32, 2.6.32-rc1, 3.0-rc6, etc. ifeq ($(findstring x2.6.,x$(LINUX_VERSION)),x2.6.) LINUX_SITE = $(BR2_KERNEL_MIRROR)/linux/kernel/v2.6 else ifeq ($(findstring x3.,x$(LINUX_VERSION)),x3.) LINUX_SITE = $(BR2_KERNEL_MIRROR)/linux/kernel/v3.x else ifeq ($(findstring x4.,x$(LINUX_VERSION)),x4.) LINUX_SITE = $(BR2_KERNEL_MIRROR)/linux/kernel/v4.x endif # release candidates are in testing/ subdir ifneq ($(findstring -rc,$(LINUX_VERSION)),) LINUX_SITE := $(LINUX_SITE)/testing endif # -rc endif LINUX_PATCHES = $(call qstrip,$(BR2_LINUX_KERNEL_PATCH)) # We rely on the generic package infrastructure to download and apply # remote patches (downloaded from ftp, http or https). For local # patches, we can't rely on that infrastructure, because there might # be directories in the patch list (unlike for other packages). LINUX_PATCH = $(filter ftp://% http://% https://%,$(LINUX_PATCHES)) LINUX_INSTALL_IMAGES = YES LINUX_DEPENDENCIES += host-kmod host-lzop host-lzma ifeq ($(BR2_LINUX_KERNEL_UBOOT_IMAGE),y) LINUX_DEPENDENCIES += host-uboot-tools endif LINUX_MAKE_FLAGS = \ HOSTCC="$(HOSTCC)" \ HOSTCFLAGS="$(HOSTCFLAGS)" \ ARCH=$(KERNEL_ARCH) \ INSTALL_MOD_PATH=$(TARGET_DIR) \ CROSS_COMPILE="$(TARGET_CROSS)" \ DEPMOD=$(HOST_DIR)/sbin/depmod LINUX_MAKE_ENV = \ $(TARGET_MAKE_ENV) \ BR_BINARIES_DIR=$(BINARIES_DIR) # Get the real Linux version, which tells us where kernel modules are # going to be installed in the target filesystem. LINUX_VERSION_PROBED = `$(MAKE) $(LINUX_MAKE_FLAGS) -C $(LINUX_DIR) --no-print-directory -s kernelrelease 2>/dev/null` ifeq ($(BR2_LINUX_KERNEL_USE_INTREE_DTS),y) KERNEL_DTS_NAME = $(call qstrip,$(BR2_LINUX_KERNEL_INTREE_DTS_NAME)) else ifeq ($(BR2_LINUX_KERNEL_USE_CUSTOM_DTS),y) # We keep only the .dts files, so that the user can specify both .dts # and .dtsi files in BR2_LINUX_KERNEL_CUSTOM_DTS_PATH. Both will be # copied to arch/<arch>/boot/dts, but only the .dts files will # actually be generated as .dtb. KERNEL_DTS_NAME = $(basename $(filter %.dts,$(notdir $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_DTS_PATH))))) endif KERNEL_DTBS = $(addsuffix .dtb,$(KERNEL_DTS_NAME)) ifeq ($(BR2_LINUX_KERNEL_IMAGE_TARGET_CUSTOM),y) LINUX_IMAGE_NAME = $(call qstrip,$(BR2_LINUX_KERNEL_IMAGE_NAME)) LINUX_TARGET_NAME = $(call qstrip,$(BR2_LINUX_KERNEL_IMAGE_TARGET_NAME)) ifeq ($(LINUX_IMAGE_NAME),) LINUX_IMAGE_NAME = $(LINUX_TARGET_NAME) endif else ifeq ($(BR2_LINUX_KERNEL_UIMAGE),y) LINUX_IMAGE_NAME = uImage else ifeq ($(BR2_LINUX_KERNEL_APPENDED_UIMAGE),y) LINUX_IMAGE_NAME = uImage else ifeq ($(BR2_LINUX_KERNEL_BZIMAGE),y) LINUX_IMAGE_NAME = bzImage else ifeq ($(BR2_LINUX_KERNEL_ZIMAGE),y) LINUX_IMAGE_NAME = zImage else ifeq ($(BR2_LINUX_KERNEL_ZIMAGE_EPAPR),y) LINUX_IMAGE_NAME = zImage.epapr else ifeq ($(BR2_LINUX_KERNEL_APPENDED_ZIMAGE),y) LINUX_IMAGE_NAME = zImage else ifeq ($(BR2_LINUX_KERNEL_CUIMAGE),y) LINUX_IMAGE_NAME = cuImage.$(KERNEL_DTS_NAME) else ifeq ($(BR2_LINUX_KERNEL_SIMPLEIMAGE),y) LINUX_IMAGE_NAME = simpleImage.$(KERNEL_DTS_NAME) else ifeq ($(BR2_LINUX_KERNEL_IMAGE),y) LINUX_IMAGE_NAME = Image else ifeq ($(BR2_LINUX_KERNEL_LINUX_BIN),y) LINUX_IMAGE_NAME = linux.bin else ifeq ($(BR2_LINUX_KERNEL_VMLINUX_BIN),y) LINUX_IMAGE_NAME = vmlinux.bin else ifeq ($(BR2_LINUX_KERNEL_VMLINUX),y) LINUX_IMAGE_NAME = vmlinux else ifeq ($(BR2_LINUX_KERNEL_VMLINUZ),y) LINUX_IMAGE_NAME = vmlinuz endif # The if-else blocks above are all the image types we know of, and all # come from a Kconfig choice, so we know we have LINUX_IMAGE_NAME set # to something LINUX_TARGET_NAME = $(LINUX_IMAGE_NAME) endif LINUX_KERNEL_UIMAGE_LOADADDR = $(call qstrip,$(BR2_LINUX_KERNEL_UIMAGE_LOADADDR)) ifneq ($(LINUX_KERNEL_UIMAGE_LOADADDR),) LINUX_MAKE_FLAGS += LOADADDR="$(LINUX_KERNEL_UIMAGE_LOADADDR)" endif # Compute the arch path, since i386 and x86_64 are in arch/x86 and not # in arch/$(KERNEL_ARCH). Even if the kernel creates symbolic links # for bzImage, arch/i386 and arch/x86_64 do not exist when copying the # defconfig file. ifeq ($(KERNEL_ARCH),i386) KERNEL_ARCH_PATH = $(LINUX_DIR)/arch/x86 else ifeq ($(KERNEL_ARCH),x86_64) KERNEL_ARCH_PATH = $(LINUX_DIR)/arch/x86 else KERNEL_ARCH_PATH = $(LINUX_DIR)/arch/$(KERNEL_ARCH) endif ifeq ($(BR2_LINUX_KERNEL_VMLINUX),y) LINUX_IMAGE_PATH = $(LINUX_DIR)/$(LINUX_IMAGE_NAME) else ifeq ($(BR2_LINUX_KERNEL_VMLINUZ),y) LINUX_IMAGE_PATH = $(LINUX_DIR)/$(LINUX_IMAGE_NAME) else LINUX_IMAGE_PATH = $(KERNEL_ARCH_PATH)/boot/$(LINUX_IMAGE_NAME) endif # BR2_LINUX_KERNEL_VMLINUX define LINUX_APPLY_LOCAL_PATCHES for p in $(filter-out ftp://% http://% https://%,$(LINUX_PATCHES)) ; do \ if test -d $$p ; then \ $(APPLY_PATCHES) $(@D) $$p \*.patch || exit 1 ; \ else \ $(APPLY_PATCHES) $(@D) `dirname $$p` `basename $$p` || exit 1; \ fi \ done endef LINUX_POST_PATCH_HOOKS += LINUX_APPLY_LOCAL_PATCHES ifeq ($(BR2_LINUX_KERNEL_USE_DEFCONFIG),y) KERNEL_SOURCE_CONFIG = $(KERNEL_ARCH_PATH)/configs/$(call qstrip,$(BR2_LINUX_KERNEL_DEFCONFIG))_defconfig else ifeq ($(BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG),y) KERNEL_SOURCE_CONFIG = $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE)) endif LINUX_KCONFIG_FILE = $(KERNEL_SOURCE_CONFIG) LINUX_KCONFIG_FRAGMENT_FILES = $(call qstrip,$(BR2_LINUX_KERNEL_CONFIG_FRAGMENT_FILES)) LINUX_KCONFIG_EDITORS = menuconfig xconfig gconfig nconfig LINUX_KCONFIG_OPTS = $(LINUX_MAKE_FLAGS) define LINUX_KCONFIG_FIXUP_CMDS $(if $(LINUX_NEEDS_MODULES), $(call KCONFIG_ENABLE_OPT,CONFIG_MODULES,$(@D)/.config)) $(if $(BR2_arm)$(BR2_armeb), $(call KCONFIG_ENABLE_OPT,CONFIG_AEABI,$(@D)/.config)) $(if $(BR2_TARGET_ROOTFS_CPIO), $(call KCONFIG_ENABLE_OPT,CONFIG_BLK_DEV_INITRD,$(@D)/.config)) # As the kernel gets compiled before root filesystems are # built, we create a fake cpio file. It'll be # replaced later by the real cpio archive, and the kernel will be # rebuilt using the linux-rebuild-with-initramfs target. $(if $(BR2_TARGET_ROOTFS_INITRAMFS), touch $(BINARIES_DIR)/rootfs.cpio $(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_SOURCE,"$${BR_BINARIES_DIR}/rootfs.cpio",$(@D)/.config) $(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_ROOT_UID,0,$(@D)/.config) $(call KCONFIG_SET_OPT,CONFIG_INITRAMFS_ROOT_GID,0,$(@D)/.config)) $(if $(BR2_ROOTFS_DEVICE_CREATION_STATIC),, $(call KCONFIG_ENABLE_OPT,CONFIG_DEVTMPFS,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_DEVTMPFS_MOUNT,$(@D)/.config)) $(if $(BR2_ROOTFS_DEVICE_CREATION_DYNAMIC_EUDEV), $(call KCONFIG_ENABLE_OPT,CONFIG_INOTIFY_USER,$(@D)/.config)) $(if $(BR2_PACKAGE_KTAP), $(call KCONFIG_ENABLE_OPT,CONFIG_DEBUG_FS,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_ENABLE_DEFAULT_TRACERS,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_PERF_EVENTS,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_FUNCTION_TRACER,$(@D)/.config)) $(if $(BR2_PACKAGE_SYSTEMD), $(call KCONFIG_ENABLE_OPT,CONFIG_CGROUPS,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_INOTIFY_USER,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_FHANDLE,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_AUTOFS4_FS,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_TMPFS_POSIX_ACL,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_TMPFS_POSIX_XATTR,$(@D)/.config)) $(if $(BR2_PACKAGE_SMACK), $(call KCONFIG_ENABLE_OPT,CONFIG_SECURITY,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_SECURITY_SMACK,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_SECURITY_NETWORK,$(@D)/.config)) $(if $(BR2_PACKAGE_IPTABLES), $(call KCONFIG_ENABLE_OPT,CONFIG_IP_NF_IPTABLES,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_IP_NF_FILTER,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_NETFILTER,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_NETFILTER_XTABLES,$(@D)/.config)) $(if $(BR2_PACKAGE_XTABLES_ADDONS), $(call KCONFIG_ENABLE_OPT,CONFIG_NETFILTER_ADVANCED,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_NF_CONNTRACK,$(@D)/.config) $(call KCONFIG_ENABLE_OPT,CONFIG_NF_CONNTRACK_MARK,$(@D)/.config)) $(if $(BR2_LINUX_KERNEL_APPENDED_DTB), $(call KCONFIG_ENABLE_OPT,CONFIG_ARM_APPENDED_DTB,$(@D)/.config)) endef ifeq ($(BR2_LINUX_KERNEL_DTS_SUPPORT),y) ifeq ($(BR2_LINUX_KERNEL_DTB_IS_SELF_BUILT),) define LINUX_BUILD_DTB $(LINUX_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(@D) $(KERNEL_DTBS) endef define LINUX_INSTALL_DTB # dtbs moved from arch/<ARCH>/boot to arch/<ARCH>/boot/dts since 3.8-rc1 cp $(addprefix \ $(KERNEL_ARCH_PATH)/boot/$(if $(wildcard \ $(addprefix $(KERNEL_ARCH_PATH)/boot/dts/,$(KERNEL_DTBS))),dts/),$(KERNEL_DTBS)) \ $(BINARIES_DIR)/ endef define LINUX_INSTALL_DTB_TARGET # dtbs moved from arch/<ARCH>/boot to arch/<ARCH>/boot/dts since 3.8-rc1 cp $(addprefix \ $(KERNEL_ARCH_PATH)/boot/$(if $(wildcard \ $(addprefix $(KERNEL_ARCH_PATH)/boot/dts/,$(KERNEL_DTBS))),dts/),$(KERNEL_DTBS)) \ $(TARGET_DIR)/boot/ endef endif endif ifeq ($(BR2_LINUX_KERNEL_APPENDED_DTB),y) # dtbs moved from arch/$ARCH/boot to arch/$ARCH/boot/dts since 3.8-rc1 define LINUX_APPEND_DTB if [ -e $(KERNEL_ARCH_PATH)/boot/$(KERNEL_DTS_NAME).dtb ]; then \ cat $(KERNEL_ARCH_PATH)/boot/$(KERNEL_DTS_NAME).dtb; \ else \ cat $(KERNEL_ARCH_PATH)/boot/dts/$(KERNEL_DTS_NAME).dtb; \ fi >> $(KERNEL_ARCH_PATH)/boot/zImage endef ifeq ($(BR2_LINUX_KERNEL_APPENDED_UIMAGE),y) # We need to generate a new u-boot image that takes into # account the extra-size added by the device tree at the end # of the image. To do so, we first need to retrieve both load # address and entry point for the kernel from the already # generate uboot image before using mkimage -l. LINUX_APPEND_DTB += $(sep) MKIMAGE_ARGS=`$(MKIMAGE) -l $(LINUX_IMAGE_PATH) |\ sed -n -e 's/Image Name:[ ]*\(.*\)/-n \1/p' -e 's/Load Address:/-a/p' -e 's/Entry Point:/-e/p'`; \ $(MKIMAGE) -A $(MKIMAGE_ARCH) -O linux \ -T kernel -C none $${MKIMAGE_ARGS} \ -d $(KERNEL_ARCH_PATH)/boot/zImage $(LINUX_IMAGE_PATH); endif endif # Compilation. We make sure the kernel gets rebuilt when the # configuration has changed. define LINUX_BUILD_CMDS $(if $(BR2_LINUX_KERNEL_USE_CUSTOM_DTS), cp $(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_DTS_PATH)) $(KERNEL_ARCH_PATH)/boot/dts/) $(LINUX_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(@D) $(LINUX_TARGET_NAME) @if grep -q "CONFIG_MODULES=y" $(@D)/.config; then \ $(LINUX_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(@D) modules ; \ fi $(LINUX_BUILD_DTB) $(LINUX_APPEND_DTB) endef ifeq ($(BR2_LINUX_KERNEL_INSTALL_TARGET),y) define LINUX_INSTALL_KERNEL_IMAGE_TO_TARGET install -m 0644 -D $(LINUX_IMAGE_PATH) $(TARGET_DIR)/boot/$(LINUX_IMAGE_NAME) $(LINUX_INSTALL_DTB_TARGET) endef endif define LINUX_INSTALL_HOST_TOOLS # Installing dtc (device tree compiler) as host tool, if selected if grep -q "CONFIG_DTC=y" $(@D)/.config; then \ $(INSTALL) -D -m 0755 $(@D)/scripts/dtc/dtc $(HOST_DIR)/usr/bin/linux-dtc ; \ fi endef define LINUX_INSTALL_IMAGES_CMDS cp $(LINUX_IMAGE_PATH) $(BINARIES_DIR) $(LINUX_INSTALL_DTB) endef define LINUX_INSTALL_TARGET_CMDS $(LINUX_INSTALL_KERNEL_IMAGE_TO_TARGET) # Install modules and remove symbolic links pointing to build # directories, not relevant on the target @if grep -q "CONFIG_MODULES=y" $(@D)/.config; then \ $(LINUX_MAKE_ENV) $(MAKE1) $(LINUX_MAKE_FLAGS) -C $(@D) modules_install; \ rm -f $(TARGET_DIR)/lib/modules/$(LINUX_VERSION_PROBED)/build ; \ rm -f $(TARGET_DIR)/lib/modules/$(LINUX_VERSION_PROBED)/source ; \ fi $(LINUX_INSTALL_HOST_TOOLS) endef # Include all our extensions and tools definitions. # # Note: our package infrastructure uses the full-path of the last-scanned # Makefile to determine what package we're currently defining, using the # last directory component in the path. As such, including other Makefile, # like below, before we call one of the *-package macro is usally not # working. # However, since the files we include here are in the same directory as # the current Makefile, we are OK. But this is a hard requirement: files # included here *must* be in the same directory! include $(sort $(wildcard linux/linux-ext-*.mk)) include $(sort $(wildcard linux/linux-tool-*.mk)) LINUX_PATCH_DEPENDENCIES += $(foreach ext,$(LINUX_EXTENSIONS),\ $(if $(BR2_LINUX_KERNEL_EXT_$(call UPPERCASE,$(ext))),$(ext))) LINUX_PRE_PATCH_HOOKS += $(foreach ext,$(LINUX_EXTENSIONS),\ $(if $(BR2_LINUX_KERNEL_EXT_$(call UPPERCASE,$(ext))),\ $(call UPPERCASE,$(ext))_PREPARE_KERNEL)) # Install Linux kernel tools in the staging directory since some tools # may install shared libraries and headers (e.g. cpupower). The kernel # image is NOT installed in the staging directory. LINUX_INSTALL_STAGING = YES LINUX_DEPENDENCIES += $(foreach tool,$(LINUX_TOOLS),\ $(if $(BR2_LINUX_KERNEL_TOOL_$(call UPPERCASE,$(tool))),\ $($(call UPPERCASE,$(tool))_DEPENDENCIES))) LINUX_POST_BUILD_HOOKS += $(foreach tool,$(LINUX_TOOLS),\ $(if $(BR2_LINUX_KERNEL_TOOL_$(call UPPERCASE,$(tool))),\ $(call UPPERCASE,$(tool))_BUILD_CMDS)) LINUX_POST_INSTALL_STAGING_HOOKS += $(foreach tool,$(LINUX_TOOLS),\ $(if $(BR2_LINUX_KERNEL_TOOL_$(call UPPERCASE,$(tool))),\ $(call UPPERCASE,$(tool))_INSTALL_STAGING_CMDS)) LINUX_POST_INSTALL_TARGET_HOOKS += $(foreach tool,$(LINUX_TOOLS),\ $(if $(BR2_LINUX_KERNEL_TOOL_$(call UPPERCASE,$(tool))),\ $(call UPPERCASE,$(tool))_INSTALL_TARGET_CMDS)) # Checks to give errors that the user can understand ifeq ($(BR_BUILDING),y) ifeq ($(BR2_LINUX_KERNEL_USE_DEFCONFIG),y) ifeq ($(call qstrip,$(BR2_LINUX_KERNEL_DEFCONFIG)),) $(error No kernel defconfig name specified, check your BR2_LINUX_KERNEL_DEFCONFIG setting) endif endif ifeq ($(BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG),y) ifeq ($(call qstrip,$(BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE)),) $(error No kernel configuration file specified, check your BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE setting) endif endif ifeq ($(BR2_LINUX_KERNEL_DTS_SUPPORT)$(KERNEL_DTS_NAME),y) $(error No kernel device tree source specified, check your \ BR2_LINUX_KERNEL_USE_INTREE_DTS / BR2_LINUX_KERNEL_USE_CUSTOM_DTS settings) endif ifeq ($(BR2_LINUX_KERNEL_APPENDED_DTB),y) ifneq ($(words $(KERNEL_DTS_NAME)),1) $(error Kernel with appended device tree needs exactly one DTS source. \ Check BR2_LINUX_KERNEL_INTREE_DTS_NAME or BR2_LINUX_KERNEL_CUSTOM_DTS_PATH.) endif endif endif # BR_BUILDING $(eval $(kconfig-package)) # Support for rebuilding the kernel after the cpio archive has # been generated in $(BINARIES_DIR)/rootfs.cpio. $(LINUX_DIR)/.stamp_initramfs_rebuilt: $(LINUX_DIR)/.stamp_target_installed $(LINUX_DIR)/.stamp_images_installed $(BINARIES_DIR)/rootfs.cpio @$(call MESSAGE,"Rebuilding kernel with initramfs") # Build the kernel. $(LINUX_MAKE_ENV) $(MAKE) $(LINUX_MAKE_FLAGS) -C $(@D) $(LINUX_TARGET_NAME) $(LINUX_APPEND_DTB) # Copy the kernel image to its final destination cp $(LINUX_IMAGE_PATH) $(BINARIES_DIR) # If there is a .ub file copy it to the final destination test ! -f $(LINUX_IMAGE_PATH).ub || cp $(LINUX_IMAGE_PATH).ub $(BINARIES_DIR) $(Q)touch $@ # The initramfs building code must make sure this target gets called # after it generated the initramfs list of files. linux-rebuild-with-initramfs: $(LINUX_DIR)/.stamp_initramfs_rebuilt
08-13
这是客户端代码package com.tplink.cloud.demo.websocket_client; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.core.convert.ConversionFailedException; import org.springframework.messaging.converter.ByteArrayMessageConverter; import org.springframework.messaging.converter.CompositeMessageConverter; import org.springframework.messaging.converter.MappingJackson2MessageConverter; import org.springframework.messaging.converter.MessageConverter; import org.springframework.messaging.converter.StringMessageConverter; import org.springframework.messaging.simp.stomp.StompCommand; import org.springframework.messaging.simp.stomp.StompFrameHandler; import org.springframework.messaging.simp.stomp.StompHeaders; import org.springframework.messaging.simp.stomp.StompSession; import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter; import org.springframework.web.socket.WebSocketHttpHeaders; import org.springframework.web.socket.client.standard.StandardWebSocketClient; import org.springframework.web.socket.messaging.WebSocketStompClient; import org.springframework.web.socket.sockjs.client.RestTemplateXhrTransport; import org.springframework.web.socket.sockjs.client.SockJsClient; import org.springframework.web.socket.sockjs.client.Transport; import org.springframework.web.socket.sockjs.client.WebSocketTransport; @SpringBootApplication public class WebsocketClientApplication { public static void main(String[] args) throws InterruptedException { // 禁用SSL验证 SSLUtil.disableSSLVerification(); // WebSocketClient webSocketClient = new StandardWebSocketClient(); List<Transport> transports = new ArrayList<>(2); transports.add(new WebSocketTransport(new StandardWebSocketClient())); transports.add(new RestTemplateXhrTransport()); SockJsClient webSocketClient = new SockJsClient(transports); WebSocketStompClient stompClient = new WebSocketStompClient(webSocketClient); List<MessageConverter> converters = new ArrayList<>(); converters.add(new MappingJackson2MessageConverter()); // 处理JSON负载 converters.add(new StringMessageConverter()); // 处理文本负载 converters.add(new StringToByteArrayConverter()); // 添加自定义转换器 converters.add(new ByteArrayMessageConverter()); // 处理二进制负载 stompClient.setMessageConverter(new CompositeMessageConverter(converters)); // stompClient.setMessageConverter(new StringMessageConverter()); // String url1 = "/api/vms/{vmsId}/ws/status"; // todo 1 修改vmsId和URL String vmsId = "a84976add940407cbd7a76d66f5e86e7"; String url = String.format("wss://aps1-vms-api-alpha3.tplinkcloud.com/api/vms/%s/ws/status", vmsId); // String url = "wss://127.0.0.1:8081/api/vms/vms-8ff225f900a44a90a937143fe6774a98/ws/status/230/xgydnmu0/websocket"; // 添加头,握手的那些http,比如cookie final WebSocketHttpHeaders headers = new WebSocketHttpHeaders(); // todo 2 修改Cookie、CSRF-TOKEN、SourceType、Content-Type headers.set("Cookie", "VMS_SID=a1-424be2a3-e2ee-44dd-8631-78783fc32ba2; JSESSIONID=0DB7E1EC77F257BA3682052772CACF1B"); headers.set("CSRF-TOKEN", "12e4018b7b5b4c9e9d21692655d956ef"); headers.set("SourceType", "vms_web"); headers.set("Content-Type", "application/json;charset=UTF-8"); // headers.set("sec-websocket-extensions", "permessage-deflate; client_max_window_bits"); // headers.set("sec-websocket-key", "I+JC3ABcYT+0B5zOlklaPQ=="); // headers.set("sec-websocket-version", "13"); // headers.set("Host", "aps1-vms-api-alpha3.tplinkcloud.com"); // 头部字段 final StompHeaders connectHeaders = new StompHeaders(); // todo 3 修改CSRF-TOKEN、accept-version connectHeaders.set("CSRF-TOKEN", "12e4018b7b5b4c9e9d21692655d956ef"); // connectHeaders.set("accept-version", "1.1,1.0"); // connectHeaders.set("heart-beat", "20000,20000"); // 链接到服务端 stompClient.connect(url, headers, connectHeaders, new StompSessionHandlerAdapter() { @Override public void afterConnected(StompSession session, StompHeaders connectedHeaders) { System.out.println("************connected"); // 订阅用户消息,"/topic/vms/{vmsId}/users/{userId}/device-add-progress/{uuid}" // todo 4 修改订阅URL String subscribeUrl = "/topic/vms/{vmsId}/users/{userId}/batch-import-device/{uuid}"; session.subscribe(subscribeUrl, new StompFrameHandler() { // @Override // public Type getPayloadType(StompHeaders headers) { // // 直接返回 Map.class,跳过二进制检查 // return Map.class; // } // @Override // public void handleFrame(StompHeaders headers, Object payload) { // if (payload instanceof Map) { // System.out.println("订阅响应: " + payload); // } // } @Override public Type getPayloadType(StompHeaders headers) { if (headers.getContentType() != null && headers.getContentType().toString().contains("application/json")) { return Map.class; // 或自定义DTO类 } return byte[].class; // 默认返回字节类型 } @Override public void handleFrame(StompHeaders headers, Object payload) { if (payload instanceof byte[]) { String jsonStr = new String((byte[]) payload, StandardCharsets.UTF_8); System.out.println("原始JSON消息: " + jsonStr); } // 处理自动转换的JSON对象 else if (payload instanceof Map) { Map<?, ?> jsonMap = (Map<?, ?>) payload; System.out.println("解析后的JSON消息: " + jsonMap); } // 处理字符串 else if (payload instanceof String) { System.out.println("文本消息: " + payload); } } }); // 构建动态路由负载 // todo 5 修改Body,一个一个看 Map<String, Object> stompPayload = new HashMap<>(); stompPayload.put("url", "https://aps1-vms-api-alpha3.tplinkcloud.com/api/v2/vms/{vmsId}/sites/{siteId}/devices/cloud/addDevicesCommon"); stompPayload.put("method", "POST"); stompPayload.put("subscribeDestination", subscribeUrl); // 路径参数 Map<String, String> pathVars = new HashMap<>(); pathVars.put("vmsId", "a84976add940407cbd7a76d66f5e86e7"); pathVars.put("siteId", "1707995954184193"); stompPayload.put("pathVars", pathVars); // 请求头 Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "application/json;charset=UTF-8"); headers.put("CSRF-TOKEN", "12e4018b7b5b4c9e9d21692655d956ef"); headers.put("x-requested-with", "XMLHttpRequest"); //暂时携带cookie // headers.put("Cookie", "JSESSIONID=873F0324DD2E9DD2B23F5A29A01DC99E; VMS_SID=v-06f73de4-a748-4893-a277-b1c7579feda1"); headers.put("SourceType", "vms_web"); stompPayload.put("headers", headers); // 请求体(业务数据) Map<String, Object> body = new HashMap<>(); body.put("username", "admin"); body.put("password", "QU+hHYz9C5crlfij1lTvm9kSgir3NrFM7A07fjYYoN3vU/Lj+we4fY5M2ZvryNRX77L9EXuV5Ml/UBidP6g6IAskoS7rPDxopjjgEchit/hdaBHOUpzf6nctUVHRoSgLnD/uqIJCv/f7/0kn8QhSThmQa8ywaLus02b4sYBNlblCbFcdOrXCqQ+4BRF2W83b15Mo8q8u2eXLM1cuQVs0dVDslj9g4zukE66kEwHO2Dq8LhjkfhL0PDaifXOWBavqdzSD7Hit5bss81zjnw6lUUODfYz/YWmxmXoOO76liMuI3fA7XqLMMH13wAeWsiuYuOv2KVKei5QtIy8+c713NA=="); List<Map<String, String>> deviceObjects = new ArrayList<>(); String[] qrCodes = { "TP14C3EFF0E1A638F582040", "TP14C3EFF0E1A62F47C2040", "TP14C3EFF0E1A6B477D2040", "TP14C3EFF0E1A6AFEF02040" // "TP14C3EFF0E1A65C1282040", "TP14C3EFF0E1A6437D82040", "TP14C3EFF0E1A67AA172040", "TP14C3EFF0E1A669FF22040", // "TP14C3EFF0E1A61B01E2040", "TP14C3EFF0E1A60E0BB2040", "TP14C3EFF0E1A696EF22040", "TP14C3EFF0E1A6CE36E2040", // "TP14C3EFF0E1A6E33592040", "TP14C3EFF0E1A6DF2BC2040", "TP14C3EFF0E1A6898AD2040", "TP14C3EFF0E1A6F52152040", // "TP14C3EFF0E1A72699B2040", "TP14C3EFF0E1A71687A2040", "TP14C3EFF0E1A73E52E2040", "TP14C3EFF0E1A7ADB8B2040", // "TP14C3EFF0E1A7407632040", "TP14C3EFF0E1A7B9DD62040", "TP14C3EFF0E1A76343B2040", "TP14C3EFF0E1A75AC5F2040", // "TP14C3EFF0E1A70D21F2040", "TP14C3EFF0E1A77620B2040", "TP14C3EFF0E1A792E392040", "TP14C3EFF0E1A78016E2040", // "TP14C3EFF0E1BE278792040", "TP14C3EFF0E1BE133D32040", "TP14C3EFF0E1BE34BA92040", "TP14C3EFF0E1BEA08EF2040", // "TP14C3EFF0E1BE4A2DA2040", "TP14C3EFF0E1BEB0B352040", "TP14C3EFF0E1BE613FF2040", "TP14C3EFF0E1BE5023D2040", // "TP14C3EFF0E1BE0F3082040", "TP14C3EFF0E1BE7319A2040", "TP14C3EFF0E1BE9C4192040", "TP14C3EFF0E1BE8A4DA2040", // "TP14C3EFF0E1BED0C332040", "TP14C3EFF0E1BECB3272040", "TP14C3EFF0E1BEF05EA2040", "TP14C3EFF0E1BEEEB102040", // "TP14C3EFF0E1BF186642040", "TP14C3EFF0E1BF056F12040", "TP14C3EFF0E1BF310D02040", "TP14C3EFF0E1BF20B912040", // "TP14C3EFF0E1BFBD10E2040", "TP14C3EFF0E1BFA6D172040", "TP14C3EFF0E1BF5B3322040", "TP14C3EFF0E1BF44BC02040", // "TP14C3EFF0E1BF705962040", "TP14C3EFF0E1BF6606D2040", "TP14C3EFF0E1BF861312040", "TP14C3EFF0E1BFFD5662040", // "TP14C3EFF0E1BF97C522040", "TP14C3EFF0E1BFC44192040", "TP14C3EFF0E1BFEAB402040", "TP14C3EFF0E1BFD44A52040", // "TP14C3EFF0E1B9A19872040", "TP14C3EFF0E1B9DFCEA2040", "TP14C3EFF0E1B9C4C452040", "TP14C3EFF0E1B9FB6AD2040", // "TP14C3EFF0E1B9E94142040", "TP14C3EFF0E1B99CD7F2040", "TP14C3EFF0E1B9892B42040", "TP14C3EFF0E1B1C42BA2040", // "TP14C3EFF0E1B1D622B2040", "TP14C3EFF0E1BBAC7812040", "TP14C3EFF0E1BB43E5B2040", "TP14C3EFF0E1BBB48D62040", // "TP14C3EFF0E1BBD066D2040", "TP14C3EFF0E1BBC1A952040", "TP14C3EFF0E1BBFF0102040", "TP14C3EFF0E1BBE25B82040", // "TP14C3EFF0E1BB9E99E2040", "TP14C3EFF0E1BB85B8C2040", "TP14C3EFF0E1B8505532040", "TP14C3EFF0E1B84E1362040", // "TP14C3EFF0E1B871B422040", "TP14C3EFF0E1B8605C32040", "TP14C3EFF0E1B8175782040", "TP14C3EFF0E1B80F12F2040", // "TP14C3EFF0E1B8320C12040", "TP14C3EFF0E1B82E1EC2040", "TP14C3EFF0E1B8B4FAC2040", "TP14C3EFF0E1B8A1C942040", // "TP14C3EFF0E1B8CC1B42040", "TP14C3EFF0E1B8E8AA42040", "TP14C3EFF0E1B8DEE662040", "TP14C3EFF0E1B8879D02040", // "TP14C3EFF0E1B8F6C9C2040", "TP14C3EFF0E1B89B3C82040", "TP14C3EFF0E1B9366462040", "TP14C3EFF0E1B945C3B2040", // "TP14C3EFF0E1B9B9FBE2040", "TP14C3EFF0E1B96160F2040", "TP14C3EFF0E1B952BE02040", "TP14C3EFF0E1B9009322040", // "TP14C3EFF0E1B97469B2040", "TP14C3EFF0E1B92E0602040", "TP14C3EFF0E1B91BF7E2040", "TP14C3EFF0E1BDAAFA42040", // "TP14C3EFF0E1BD4CBD82040", "TP14C3EFF0E1BDB652E2040", "TP14C3EFF0E1BD6D1E92040", "TP14C3EFF0E1A5D9FB12040", // "TP14C3EFF0E1BD58D462040", "TP14C3EFF0E1A5C9CA52040", "TP14C3EFF0E1BDF2B6C2040", "TP14C3EFF0E1A27A74B2040", // "TP14C3EFF0E1BDE59202040", "TP14C3EFF0E1A26816C2040", "TP14C3EFF0E1BD9AD8A2040", "TP14C3EFF0E1A21C7392040", // "TP14C3EFF0E1BD8E3A52040", "TP14C3EFF0E1A209BC32040", "TP14C3EFF0E1A2337F12040", "TP14C3EFF0E1A227C1A2040", // "TP14C3EFF0E1BDD8DC02040", "TP14C3EFF0E1BDC723E2040", "TP14C3EFF0E1BA79A162040", "TP14C3EFF0E1BA6ED472040", // "TP14C3EFF0E1BA187232040", "TP14C3EFF0E1BA053972040", "TP14C3EFF0E1BA36CC52040", "TP14C3EFF0E1BA2072B2040", // "TP14C3EFF0E1BAB5FEB2040", "TP14C3EFF0E1BAADBE52040", "TP14C3EFF0E1BA52C812040", "TP14C3EFF0E1BA473B72040", // "TP14C3EFF0E1BAEC1DB2040", "TP14C3EFF0E1BAD26E72040", "TP14C3EFF0E1BA8776F2040", "TP14C3EFF0E1BAF73E72040", // "TP14C3EFF0E1BA9DAEA2040", "TP14C3EFF0E1BACCEF22040", "TP14C3EFF0E1BB69E532040", "TP14C3EFF0E1BB58E762040", // "TP14C3EFF0E1BB00E992040", "TP14C3EFF0E1BB7E7C62040", "TP14C3EFF0E1BB2EFD72040", "TP14C3EFF0E1BB172E12040", // "TP14C3EFF0E1BB34E872040", "TP14C3EFF0E1A7D5DFA2040", "TP14C3EFF0E1A7C04142040", "TP14C3EFF0E1A7F0EE62040", // "TP14C3EFF0E1A7E30402040", "TP14C3EFF0E1A41BC4D2040", "TP14C3EFF0E1A40CE712040", "TP14C3EFF0E1A438B152040", // "TP14C3EFF0E1A42D1612040", "TP14C3EFF0E1A4B89712040", "TP14C3EFF0E1A4A4E542040", "TP14C3EFF0E1A45A8492040", // "TP14C3EFF0E1A44AAE42040", "TP14C3EFF0E1A475DBC2040", "TP14C3EFF0E1A464A042040", "TP14C3EFF0E1BC1A80C2040", // "TP14C3EFF0E1A4832F12040", "TP14C3EFF0E1BC0BABE2040", "TP14C3EFF0E1A4F78132040", "TP14C3EFF0E1BC3BD3E2040", // "TP14C3EFF0E1BC2A2832040", "TP14C3EFF0E1A49E4022040", "TP14C3EFF0E1BCB79282040", "TP14C3EFF0E1BCAC7072040", // "TP14C3EFF0E1BC5DF1C2040", "TP14C3EFF0E1A4CDD4C2040", "TP14C3EFF0E1BC40FB52040", "TP14C3EFF0E1BC7CF832040", // "TP14C3EFF0E1A4EB2712040", "TP14C3EFF0E1BC648DC2040", "TP14C3EFF0E1A4D08262040", "TP14C3EFF0E1BC8699D2040", // "TP14C3EFF0E1A50AEA82040", "TP14C3EFF0E1BCF1F0E2040", "TP14C3EFF0E1A57F7862040", "TP14C3EFF0E1A525BA42040", // "TP14C3EFF0E1BC9CD8C2040", "TP14C3EFF0E1A517A292040", "TP14C3EFF0E1A5322682040", "TP14C3EFF0E1A5A83BC2040", // "TP14C3EFF0E1BCCEE7E2040", "TP14C3EFF0E1A5436512040", "TP14C3EFF0E1A5BFE3D2040", "TP14C3EFF0E1BCEA8142040", // "TP14C3EFF0E1A564A4C2040", "TP14C3EFF0E1BCDAAB42040", "TP14C3EFF0E1A5539AF2040", "TP14C3EFF0E1BD093C22040", // "TP14C3EFF0E1A5F12202040", "TP14C3EFF0E1BD7592C2040", "TP14C3EFF0E1A5E39702040", "TP14C3EFF0E1BD2C15C2040", // "TP14C3EFF0E1A5955402040", "TP14C3EFF0E1BD142BD2040", "TP14C3EFF0E1A58F8E02040", "TP14C3EFF0E1BD3FAE82040" }; for (String qrCode : qrCodes) { Map<String, String> device = new HashMap<>(); device.put("qrCode", qrCode); deviceObjects.add(device); } body.put("deviceList", deviceObjects); // 添加其他业务字段... body.put("importId", "54f8ea77e135017ef4f6de7bf0726585"); body.put("needInitDevice", false); body.put("whetherRsa", true); stompPayload.put("body", body); // 发送优化后的STOMP消息 String sendDestination = "/vms/{vmsId}/httpoversend/{taskId}" .replace("{vmsId}", pathVars.get("vmsId")) .replace("{taskId}", pathVars.get("siteId")); // 替换为实际taskId session.send(sendDestination, stompPayload); } @Override public void handleException(StompSession session, StompCommand command, StompHeaders headers, byte[] payload, Throwable exception) { System.err.println("STOMP Exception: " + exception.getMessage()); } @Override public void handleTransportError(StompSession session, Throwable exception) { System.err.println("Transport Error: " + exception.getMessage()); if (exception instanceof ConversionFailedException) { System.out.println("Conversion Failed"); } exception.printStackTrace(); // 关键:添加堆栈信息 } }); System.out.println("客户端已启动,阻塞主线程等待消息..."); Thread.sleep(Long.MAX_VALUE); // 永久阻塞主线程 } } 这是服务端部分代码: private void publishImportProgress(String vmsId, String userId, ImportDevicePublishDTO publishDTO, Boolean fromCentral) { Map<String, String> variables = new HashMap<>(2); variables.put("vmsId", vmsId); variables.put("uuid", publishDTO.getImportId()); Integer sn = getAndIncrementSn(publishDTO.getImportId()); WebSocketOperationResponse<ImportDevicePublishDTO> wsResponse; if (Objects.equals(publishDTO.getStatus(), DeviceConstant.BATCH_DEVICE_IMPORT_SUCCESS) || Objects.equals(publishDTO.getStatus(), DeviceConstant.BATCH_DEVICE_IMPORT_NEED_INIT)) { wsResponse = WebSocketOperationResponse.processCompleteMessage(publishDTO.getImportId(), sn, publishDTO); } else if (Objects.equals(publishDTO.getStatus(), DeviceConstant.BATCH_DEVICE_IMPORTING)) { wsResponse = WebSocketOperationResponse.processMessage(publishDTO.getImportId(), sn, publishDTO); } else { // 错误状态 wsResponse = WebSocketOperationResponse.processErrorMessage( ResponseCode.findByCode(publishDTO.getErrorCodes().get(0)), publishDTO.getImportId()); wsResponse.setData(publishDTO); } // todo 后续删除单播 StompMessage unicastMessage = StompMessage.fromUnicast(StompDestinationEnum.BATCH_IMPORT_DEVICE_UNICAST, variables, wsResponse, Collections.emptyList(), Collections.singletonList(userId)); String unicastJson = JsonUtils.bean2Json(unicastMessage); publisher.publishAsynProxy(EventTopicConstant.WEBSOCKET_MESSAGE_SEND_EVENT, vmsId, unicastJson, StompConstant.FILTER_KEY_WEB); // 发送广播 StompMessage message = StompMessage.fromBroadcast(StompDestinationEnum.BATCH_IMPORT_DEVICE, variables, wsResponse); String json = JsonUtils.bean2Json(message); publisher.publishAsynProxy(EventTopicConstant.WEBSOCKET_MESSAGE_SEND_EVENT, vmsId, json, StompConstant.FILTER_KEY_WEB); // 同时向central 推送进度 if (Boolean.TRUE.equals(fromCentral)) { log.info("start to report sur device import progress to omada central, vmsId:{}", vmsId); occuredService.pushImportProgress2OmadaCentral(publishDTO); } } @Trace public OperationResponse<Void> importDevices(AddCloudDeviceDTO<AddDeviceByQrCodeDTO> deviceDTO, boolean addPwdWrongDevice, int total, List<AddDeviceByQrCodeResult> failedDeviceResultList, String loginUserName, String source, String method) { // 1. 入口日志:记录完整请求体(脱敏处理) log.debug("[DEV] ==== 批量导入开始 ==== | vmsId:{} | importId:{} | 设备总数:{} | 模式:{}", deviceDTO.getVmsId(), deviceDTO.getImportId(), total, addPwdWrongDevice ? "密码错误重试" : "首次导入"); Boolean fromCentral = deviceDTO.getFromCentral(); String vmsId = deviceDTO.getVmsId(); String importId = deviceDTO.getImportId(); String userId = deviceDTO.getUserId(); List<AddDeviceByQrCodeDTO> qrCodeDTOs = deviceDTO.getDeviceList(); Map<String, AddDeviceByQrCodeDTO> qrCode2AddParamMap = new HashMap<>(); if (log.isDebugEnabled()) { log.debug("start to import device: {}", CustomPIIMaskUtil.parseToStr(deviceDTO)); } Set<String> validQrCodes = new HashSet<>(); // 有效设备 List<AddDeviceByQrCodeDTO> validQrCodDTOs = new ArrayList<>(qrCodeDTOs.size()); for (AddDeviceByQrCodeDTO qrCodeDTO : qrCodeDTOs) { String qrCode = qrCodeDTO.getQrCode(); // 2. 设备二维码验证日志 log.debug("[DEV] 处理设备二维码: {}", CustomPIIMaskUtil.encrypt(qrCodeDTO.getQrCode())); if (StringUtils.isBlank(qrCode)) { log.warn("empty qrcode :{}", CustomPIIMaskUtil.parseToStr(qrCodeDTO)); continue; } AddDeviceByQrCodeResult result = new AddDeviceByQrCodeResult(); result.setQrCode(qrCode); Matcher matcher = SN_DEVICE_ID_REGEX.matcher(qrCode); if (!matcher.find()) { result.setErrorCode(ResponseCode.PARAM_INVALID.getCode()); failedDeviceResultList.add(result); continue; } if (validQrCodes.contains(qrCode)) { result.setErrorCode(ResponseCode.DUPLICATE_QR_CODE.getCode()); failedDeviceResultList.add(result); continue; } String formatQrCode = getFormatQrCode(qrCode); if (qrCode2AddParamMap.containsKey(formatQrCode)) { result.setErrorCode(ResponseCode.DUPLICATE_QR_CODE.getCode()); failedDeviceResultList.add(result); continue; } // 过滤有效的参数 validQrCodes.add(qrCode); validQrCodDTOs.add(qrCodeDTO); qrCode2AddParamMap.put(formatQrCode, qrCodeDTO); } // 构建初始进度并推送 ImportDevicePublishDTO importDevicePublishDTO = buildImportDevicePublishDTO(importId, total, deviceDTO.getSiteId()); if (addPwdWrongDevice) { importDevicePublishDTO.setFail(failedDeviceResultList.size()); // 总数减去失败数和待添加数为成功数 importDevicePublishDTO.setSuccess(total - failedDeviceResultList.size() - qrCodeDTOs.size()); } publishImportProgress(vmsId, userId, importDevicePublishDTO, fromCentral); // 批量获取deviceIds // 3. 云端设备信息获取日志 log.debug("[DEV] 有效二维码数量: {} | 开始获取基础云设备信息", validQrCodDTOs.size()); List<GetDeviceInfoItem> deviceList = getAllDeviceInfo(validQrCodDTOs, deviceDTO.getUserId()); List<String> deviceIds = deviceList.stream().map(GetDeviceInfoItem::getDeviceId).filter(StringUtils::isNotBlank) .distinct().collect(Collectors.toList()); log.debug("[DEV] 基础云返回设备数: {} | 有效deviceId数: {}", deviceList.size(), deviceIds.size()); Map<String, GetDeviceInfoItem> formatQrCode2DeviceIdInfoMap = deviceList.stream() .collect(Collectors.toMap(GetDeviceInfoItem::getId, Function.identity(), (v1, v2) -> v2)); // 批量获取设备信息 List<DeviceInfoItem> deviceInfoItems = batchGetDeviceInfo(deviceIds); Map<String, DeviceInfoItem> deviceId2DeviceInfoMap = deviceInfoItems.stream() .filter(deviceInfoItem -> StringUtils.isNotBlank(deviceInfoItem.getDeviceId())) .collect(Collectors.toMap(DeviceInfoItem::getDeviceId, Function.identity(), (v1, v2) -> v2)); // 获取设备SN Map<String, String> deviceSnMap = deviceSnInfoService.getDeviceSnMap(deviceList, deviceId2DeviceInfoMap); // 成功数 AtomicInteger successCount = new AtomicInteger(0); // 失败数 AtomicInteger failCount = new AtomicInteger(failedDeviceResultList.size()); List<String> failDevIds = new ArrayList<>(); Map<String, Future<AddDeviceByQrCodeResult>> addResult = new HashMap<>(); List<String> successDeviceList = new ArrayList<>(); final RetryAddDevicePublishDTO retryAddDevicePublishDTO = new RetryAddDevicePublishDTO(); retryAddDevicePublishDTO.setImportId(importId); retryAddDevicePublishDTO.setSiteId(deviceDTO.getSiteId()); retryAddDevicePublishDTO.setStatus(DeviceConstant.BATCH_DEVICE_IMPORTING); deviceDTO.setRootSiteId(querySiteService.getRootSiteId(deviceDTO.getVmsId(), deviceDTO.getSiteId())); VmsType vmsType = vmsTypeCache.getVmsType(vmsId); for (Map.Entry<String, AddDeviceByQrCodeDTO> addEntry : qrCode2AddParamMap.entrySet()) { AddDeviceByQrCodeResult result = new AddDeviceByQrCodeResult(); String formatQrCode = addEntry.getKey(); AddDeviceByQrCodeDTO addDeviceByQrCodeDTO = addEntry.getValue(); // 设置为初始的qrcode String originalQrCode = addDeviceByQrCodeDTO.getQrCode(); result.setQrCode(originalQrCode); String verifyPassword = StringUtils.isBlank(deviceDTO.getPassword()) ? addEntry.getValue().getPassword() : deviceDTO.getPassword(); result.setPassword(verifyPassword); GetDeviceInfoItem getDeviceInfoItem = formatQrCode2DeviceIdInfoMap.get(formatQrCode); // 是否获取到设备信息 if (getDeviceInfoItem == null || !Objects.equals(getDeviceInfoItem.getErrorCode(), ResponseCode.OK.getCode())) { result.setErrorCode(ResponseCode.FAIL_TO_GET_DEVICE_INFO.getCode()); failedDeviceResultList.add(result); importDevicePublishDTO.setFail(failCount.incrementAndGet()); publishImportProgress(vmsId, userId, importDevicePublishDTO, fromCentral); continue; } // 设备从基础云获取的deviceId String devId = getDeviceInfoItem.getDeviceId(); if (StringUtils.isEmpty(devId)) { result.setErrorCode(ResponseCode.FAIL_TO_GET_DEVICE_INFO.getCode()); failedDeviceResultList.add(result); importDevicePublishDTO.setFail(failCount.incrementAndGet()); failDevIds.add(devId); publishImportProgress(vmsId, userId, importDevicePublishDTO, fromCentral); continue; } // 判断是否还在待添加列表 if (!deviceIds.contains(devId)) { continue; } // 移除待添加列表 deviceIds.remove(devId); String deviceUserName = StringUtils.isBlank(deviceDTO.getUsername()) ? LOCAL_USER_NAME : deviceDTO.getUsername(); // 判断设备是否已存在 DeviceDO existedDeviceDO = deviceRepository.findByDevId(devId).orElse(null); if (existedDeviceDO != null) { result.setErrorCode(checkDeviceExist(vmsId, deviceDTO.getSiteId(), existedDeviceDO).getCode()); result.setDeviceModel(existedDeviceDO.getDeviceModel()); result.setDeviceType(existedDeviceDO.getDeviceType()); result.setDeviceName(existedDeviceDO.getDeviceName()); failedDeviceResultList.add(result); importDevicePublishDTO.setFail(failCount.incrementAndGet()); failDevIds.add(devId); publishImportProgress(vmsId, userId, importDevicePublishDTO, fromCentral); continue; } // 4. 单设备处理日志 log.debug("[DEV] 开始添加设备 | QR:{} | devId:{}", CustomPIIMaskUtil.encrypt(originalQrCode), CustomPIIMaskUtil.encrypt(devId)); // 线程池处理 Future<AddDeviceByQrCodeResult> responseCodeFuture = batchAddDeviceExecutor.submit(() -> { AddDeviceByQrCodeResult addDeviceByQrCodeResult = new AddDeviceByQrCodeResult(); addDeviceByQrCodeResult.setQrCode(originalQrCode); addDeviceByQrCodeResult.setDevId(devId); DeviceInfoItem item = deviceId2DeviceInfoMap.get(devId); addDeviceByQrCodeResult.setDeviceName(item.getAlias()); addDeviceByQrCodeResult.setDeviceModel(item.getDeviceModel()); addDeviceByQrCodeResult.setAddStatus(DEVICE_STATUS_ADDING); if (StringUtils.isNotEmpty(verifyPassword)) { addDeviceByQrCodeResult.setPassword(verifyPassword); } else { if (deviceDTO.getInitSetting() != null) { addDeviceByQrCodeResult.setPassword(deviceDTO.getInitSetting().getPassword()); } } retryAddDevicePublishDTO.setDevices(Collections.singletonList(addDeviceByQrCodeResult)); // 5. 线程任务执行日志 log.debug("[DEV] 提交添加任务 | QR:{} | devId:{}", CustomPIIMaskUtil.encrypt(originalQrCode), CustomPIIMaskUtil.encrypt(devId)); OperationResponse<Long> response = addSingleCloudDevice(devId, originalQrCode, deviceDTO, deviceId2DeviceInfoMap, verifyPassword, deviceUserName, deviceSnMap.get(devId), loginUserName, vmsType); addDeviceByQrCodeResult.setErrorCode(response.getErrorCode()); addDeviceByQrCodeResult.setSecLeft(response.getResult()); log.debug("[DEV] 设备添加结果 | QR:{} | 状态:{} | 错误码:{}", CustomPIIMaskUtil.encrypt(originalQrCode), response.isOk() ? "成功" : "失败", response.getErrorCode()); lockService.doWithTryLock(LOCK_BATCH_IMPORT_PROGRESS, importId, 60, TimeUnit.SECONDS, () -> { //判断添加结果 if (Objects.equals(response.getErrorCode(), ResponseCode.OK.getCode())) { importDevicePublishDTO.setSuccess(successCount.incrementAndGet()); subscribeDeviceEvents(devId); successDeviceList.add(devId); } else { importDevicePublishDTO.setFail(failCount.incrementAndGet()); failDevIds.add(devId); result.setErrorCode(response.getErrorCode()); result.setSecLeft(response.getResult()); } publishImportProgress(vmsId, userId, importDevicePublishDTO, fromCentral); addDeviceByQrCodeResult.setErrorCode(response.getErrorCode()); addDeviceByQrCodeResult.setAddStatus(DEVICE_STATUS_FINISHED); addDeviceByQrCodeResult.setSecLeft(response.getResult()); DeviceDO deviceDO = deviceRepository.findByVmsIdAndDevId(vmsId, devId).orElse(null); if (deviceDO != null) { addDeviceByQrCodeResult.setDeviceId(deviceDO.getId()); addDeviceByQrCodeResult.setMacAddress(deviceDO.getMacAddress()); addDeviceByQrCodeResult.setDeviceType(deviceDO.getDeviceType()); addDeviceByQrCodeResult.setPassword(deviceDO.getPassword()); } retryAddDevicePublishDTO.setDevices(Collections.singletonList(addDeviceByQrCodeResult)); publishRetryProgressDTO(vmsId, userId, retryAddDevicePublishDTO); return null; }, () -> { log.warn("fail to get lock to push progress :{}", importId); return null; }); return addDeviceByQrCodeResult; }); addResult.put(originalQrCode, responseCodeFuture); } List<AddDeviceByQrCodeResult> successDeviceResultList = new ArrayList<>(); try { for (Map.Entry<String, Future<AddDeviceByQrCodeResult>> entry : addResult.entrySet()) { String originalQrCode = entry.getKey(); Integer responseCode = entry.getValue().get().getErrorCode(); log.debug("add result originalQrCode:{}, response :{},", originalQrCode, responseCode); if (!ObjectUtil.equals(responseCode, ResponseCode.OK.getCode())) { failedDeviceResultList.add(entry.getValue().get()); } else { successDeviceResultList.add(entry.getValue().get()); } } } catch (Exception e) { log.warn("fail to get add result :{}, importId :{}", JsonUtils.bean2Json(addResult), importId, e); } // 查找是否有mac冲突的设备并缓存 importDevicePublishDTO.setMacConflict(false); List<AddDeviceByQrCodeResult> successConflictDevices = new ArrayList<>(); List<String> ipcMacAddressList = successDeviceResultList.stream() .filter(result -> result.getDeviceType() == DeviceType.IPC) .map(AddDeviceByQrCodeResult::getMacAddress) .collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(ipcMacAddressList)) { Set<Long> macConflictIpcIdSet = new HashSet<>(); Set<String> duplicateChannelMac = ipcRepository.findMacDuplicateChannel(vmsId, ipcMacAddressList); Iterator<AddDeviceByQrCodeResult> iterator = successDeviceResultList.iterator(); while (iterator.hasNext()) { AddDeviceByQrCodeResult deviceEntry = iterator.next(); if (deviceEntry.getDeviceType() == DeviceType.IPC && duplicateChannelMac.contains(deviceEntry.getMacAddress())) { macConflictIpcIdSet.add(deviceEntry.getDeviceId()); // 把有mac冲突的ipc从successDeviceResultList移到successConflictDevices successConflictDevices.add(deviceEntry); iterator.remove(); } } if (!macConflictIpcIdSet.isEmpty()) { importDevicePublishDTO.setMacConflict(true); String taskId = IdUtil.simpleUUID(); importDevicePublishDTO.setTaskId(taskId); deviceAddMacConflictResultCache.setMacConflictResult(vmsId, taskId, new MacConflictDeviceCacheDTO(deviceDTO.getSiteId(), macConflictIpcIdSet)); } } // 等待2s在推送结束结果 try { Thread.sleep(2000); } catch (Exception e1) { log.warn("fail to wait finish publish", e1); } List<Integer> errorCodes = failedDeviceResultList.stream().map(AddDeviceByQrCodeResult::getErrorCode).distinct() .collect(Collectors.toList()); // 判断推送完成状态 // 监控指标添加设备失败数量 log.debug("importDevices, failed list size: {}", failedDeviceResultList.size()); CountEachDeviceAddedReq reqFail = CountEachDeviceAddedReq.builder() .deviceResultList(failedDeviceResultList) .source(source) .method(method).build(); countDeviceAddedCommonService.countEachDeviceAdded(reqFail); // 监控指标添加设备成功数量 log.debug("importDevices, success list size: {}", successDeviceResultList.size()); CountEachDeviceAddedReq reqSuccess = CountEachDeviceAddedReq.builder() .deviceResultList(successDeviceResultList) .source(source) .method(method).build(); countDeviceAddedCommonService.countEachDeviceAdded(reqSuccess); Integer finishStatus = DeviceConstant.BATCH_DEVICE_IMPORT_SUCCESS; boolean needInitDevices = !addPwdWrongDevice && failedDeviceResultList.stream().anyMatch(item -> Objects.equals(ResponseCode.DEVICE_NOT_INITED.getCode(), item.getErrorCode())); if (needInitDevices) { finishStatus = DeviceConstant.BATCH_DEVICE_IMPORT_NEED_INIT; } importDevicePublishDTO.setStatus(finishStatus); importDevicePublishDTO.setFailDevices(failedDeviceResultList); importDevicePublishDTO.setSuccessDevices(successDeviceResultList); importDevicePublishDTO.setSuccessConflictDevices(successConflictDevices); importDevicePublishDTO.setFail(failedDeviceResultList.size()); importDevicePublishDTO.setSuccess(successDeviceResultList.size()); importDevicePublishDTO.setErrorCodes(errorCodes); importDevicePublishDTO.setSitePathInfos(buildSitePathInfos(vmsId, deviceDTO.getSiteId())); publishImportProgress(vmsId, userId, importDevicePublishDTO, fromCentral); List<AddDeviceByQrCodeResult> devices = new ArrayList<>(importDevicePublishDTO.getTotal()); devices.addAll(failedDeviceResultList); devices.addAll(successDeviceResultList); retryAddDevicePublishDTO.setDevices(devices); retryAddDevicePublishDTO.setErrorCodes(errorCodes); retryAddDevicePublishDTO.setStatus(finishStatus); publishRetryProgressDTO(vmsId, userId, retryAddDevicePublishDTO); // 是否有需要初始化的情况 if (needInitDevices) { BatchImportDeviceCacheDTO cacheDTO = new BatchImportDeviceCacheDTO(); cacheDTO.setTotal(total); cacheDTO.setResults(failedDeviceResultList); importDeviceCacheService.setCache(importId, cacheDTO); } if (CollectionUtils.isNotEmpty(successDeviceList)) { String accountId = getVmsOwnerAccountId(deviceDTO.getVmsId()); handleSuccessDevices(vmsId, deviceDTO.getSiteId(), successDeviceList, accountId, deviceDTO.getTplinkIdToken(), loginUserName, deviceDTO.getSourceType(), deviceDTO.getSourceIp(), deviceDTO.getFromCentral()); } if (importDevicePublishDTO.getFail() != null && importDevicePublishDTO.getFail() > 0) { handleFailedDevices(deviceDTO.getVmsId(), deviceDTO.getSiteId(), importDevicePublishDTO.getFail(), deviceDTO.getFromCentral(), loginUserName, deviceDTO.getSourceType(), deviceDTO.getSourceIp(), failDevIds); } // 7. 结束日志,删除了开始时间 log.debug("[DEV] ==== 批量导入结束 ==== | importId:{} | 总耗时:{}ms", importId, System.currentTimeMillis()); return OperationResponse.ok(); }为什么客户端没有接收到推送的消息呢
10-26
优化sql:SELECT we.organization_id ,we.wip_entity_id ,case when wl.line_id is null then we.wip_entity_name else '' end wip_entity_name ,we.primary_item_id ,mtt.transaction_type_name ,mmt.transaction_date ,bd.department_code ,mmt.inventory_item_id ,mmt.subinventory_code ,mta.reference_account ,br.resource_code ,lu2.meaning as line_type_name ,mta.base_transaction_value ,mta.cost_element_id ,flv.meaning as cost_element ,wdj.class_code job_type_code ,ml.meaning job_type_name FROM (select * from gerp.mtl_material_transactions where substr(transaction_date,1,7) >= '2023-06' and transaction_source_type_id = 5) mmt inner join gerp.wip_entities we on mmt.organization_id = we.organization_id inner join gerp.mtl_transaction_accounts mta on mta.transaction_source_id = we.wip_entity_id and mta.transaction_id = mmt.transaction_id and mta.transaction_source_type_id = 5 inner join gerp.mtl_transaction_types mtt on mtt.transaction_type_id = mmt.transaction_type_id inner join mfg_lookups lu2 on lu2.lookup_code = mta.accounting_line_type and lu2.lookup_type = 'CST_ACCOUNTING_LINE_TYPE' inner join gerp.mtl_system_items_b msi on msi.inventory_item_id = mmt.inventory_item_id and msi.organization_id = mta.organization_id left join gerp.bom_departments bd on bd.department_id = mmt.department_id left join gerp.bom_resources br on br.resource_id = mta.resource_id left join gerp.wip_lines wl on wl.line_id = mmt.repetitive_line_id left join gerp.wip_discrete_jobs wdj on wdj.wip_entity_id = mta.transaction_source_id left join gerp.fnd_lookup_values_vl flv on cast(mta.cost_element_id as string) = flv.lookup_code and flv.lookup_type = 'CST_COST_CODE_TYPE' left join mfg_lookups ml on ml.lookup_code = wdj.job_type and ml.lookup_type = 'WIP_DISCRETE_JOB' 。其中mmt,we,mta,msi,wdj数据量很大
06-10
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值