前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >鸿蒙之接收UDP消息

鸿蒙之接收UDP消息

作者头像
跋扈洋
发布于 2022-03-29 00:45:06
发布于 2022-03-29 00:45:06
1.4K00
代码可运行
举报
文章被收录于专栏:物联网知识物联网知识
运行总次数:0
代码可运行

开发环境

  1. VS Code
  2. HUAWEI DevEco Device Tool(HarmonyOS面向智能设备开发者提供的一站式集成开发环境)
  3. HiBurn(用于烧录)
  4. VMware
  5. UbuntuLinux系统)

使用的技术

UDP

Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。 Internet 的传输层有两个主要协议,互为补充。无连接的是 UDP,它除了给应用程序发送数据包功能并允许它们在所需的层次上架构自己的协议之外,几乎没有做什么特别的事情。面向连接的是 TCP,该协议几乎做了所有的事情。 UDP协议与TCP协议一样用于处理数据包,在OSI模型中,两者都位于传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但即使在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。 方法 说明 Close 关闭 UDP 连接 Connect 建立与远程主机的连接 DropMulticastGroup 退出多路广播组 JoinMulticastGroup 将 UdpClient 添加到多路广播组 Receive 返回已由远程主机发送的 UDP 数据文报 Send 将 UDP 数据文报发送到远程主机

方法

说明

Close

关闭 UDP 连接

Connect

建立与远程主机的连接

DropMulticastGroup

退出多路广播组

JoinMulticastGroup

将 UdpClient 添加到多路广播组

Receive

返回已由远程主机发送的 UDP 数据文报

Send

将 UDP 数据文报发送到远程主机

JSON

JSON介绍

JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

JSON 语法规则

JSON是一个标记符的序列。这套标记符包含六个构造字符、字符串、数字和三个字面名。 JSON是一个序列化的对象或数组。

  1. 六个构造字符: begin-array = ws %x5B ws ; [ 左方括号 begin-object = ws %x7B ws ; { 左大括号 end-array = ws %x5D ws ; ] 右方括号 end-object = ws %x7D ws ; } 右大括号 name-separator = ws %x3A ws ; : 冒号 value-separator = ws %x2C ws ; , 逗号
  2. 在这六个构造字符的前或后允许存在无意义的空白符(ws): ws = *(%x20 /; 空间 %x09 /; 水平标签 %x0A /; 换行或换行 %x0D); 回程
  3. JSON的值 JSON的构成: ws 值 ws [1] 值可以是对象、数组、数字、字符串或者三个字面值(false、null、true)中的一个。值中的字面值中的英文必须使用小写。 对象由花括号括起来的逗号分割的成员构成,成员是字符串键和上文所述的值由逗号分割的键值对组成,如: 1

{“name”: “John Doe”, “age”: 18, “address”: {“country” : “china”, “zip-code”: “10000”}}

数组是由方括号括起来的一组值构成,如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[3, 1, 4, 1, 5, 9, 2, 6]

字符串与C或者Java的字符串非常相似。字符串是由双引号包围的任意数量Unicode字符的集合,使用反斜线转义。一个字符(character)即一个单独的字符串(character string)。 数字也与C或者Java的数值非常相似。除去未曾使用的八进制与十六进制格式。除去一些编码细节。 一些合法的JSON的实例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{"a": 1, "b": [1, 2, 3]}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[1, 2, "3", {"a": 4}]
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
3.14
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"wulianwangzhishi"

具体设计

文件结构

先在./applications/sample/wifi-iot/app路径下新建一个目录(或一套目录结构),用于存放业务源码文件。 本例程:在app下新增业务led,其中hello_world.c为业务代码,BUILD.gn为编译脚本,具体规划目录结构如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
└── applications
    └── sample
        └── wifi-iot
            └── app
                │── led
                │  │── led.c
                │  └── BUILD.gn
                └── BUILD.gn

功能实现

新建./applications/sample/wifi-iot/app/led下的led.c文件,在led.c中新建业务入口函数led,并实现业务逻辑。并在代码最下方,使用HarmonyOS启动恢复模块接口SYS_RUN()启动业务。(SYS_RUN定义在ohos_init.h文件中)

BUILD.gn为编译脚本 led.c为业务逻辑代码所在文件

BUILD.gn(app/led/BUILD.gn)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static_library("bahuyang") {
    sources = [
        "led.c"
    ]

    include_dirs = [
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//base/iot_hardware/interfaces/kits/wifiiot_lite",
    ]
}
  1. “bahuyang”:是生成静态库名称,可随意更改
  2. “led.c”:代码文件

BUILD.gn(app\BUILD.gn)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import("//build/lite/config/component/lite_component.gni")

lite_component("app") {
    features = [
        #"startup",
        "led:bahuyang"
    ]
}
  1. 将"startup"注释,运行我们自己的文件
  2. “led”:工程目录
  3. bahuyang:静态库文件

搭建的模块

  1. WiFi模块
  2. OLED显示屏
  3. 红绿黄三色交通灯

主要代码

sta联网

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#define APP_INIT_VAP_NUM    2
#define APP_INIT_USR_NUM    2
volatile char start_wifi_connected_flg = 0;
static struct netif *g_lwip_netif = NULL;
void hi_sta_reset_addr(struct netif *pst_lwip_netif)
{
    ip4_addr_t st_gw;
    ip4_addr_t st_ipaddr;
    ip4_addr_t st_netmask;
    printf("%s %d \r\n", __FILE__, __LINE__);
    if (pst_lwip_netif == NULL) {
        printf("hisi_reset_addr::Null param of netdev\r\n");
        return;
    }
    IP4_ADDR(&st_gw, 0, 0, 0, 0);
    IP4_ADDR(&st_ipaddr, 0, 0, 0, 0);
    IP4_ADDR(&st_netmask, 0, 0, 0, 0);

    netifapi_netif_set_addr(pst_lwip_netif, &st_ipaddr, &st_netmask, &st_gw);
}

void wifi_wpa_event_cb(const hi_wifi_event *hisi_event)
{
    if (hisi_event == NULL)
        return;

    switch (hisi_event->event) {
        case HI_WIFI_EVT_SCAN_DONE:
            printf("WiFi: Scan results available\n");
            break;
        case HI_WIFI_EVT_CONNECTED:
            printf("WiFi: Connected\n");
            netifapi_dhcp_start(g_lwip_netif);

            start_wifi_connected_flg = 1;

            break;
        case HI_WIFI_EVT_DISCONNECTED:
            printf("WiFi: Disconnected\n");
            netifapi_dhcp_stop(g_lwip_netif);
            hi_sta_reset_addr(g_lwip_netif);
            break;
        case HI_WIFI_EVT_WPS_TIMEOUT:
            printf("WiFi: wps is timeout\n");
            break;
        default:
            break;
    }
}

int hi_wifi_start_connect(void)
{
    int ret;
    errno_t rc;
    hi_wifi_assoc_request assoc_req = {0};

    /* copy SSID to assoc_req */
    //热点名称
    rc = memcpy_s(assoc_req.ssid, HI_WIFI_MAX_SSID_LEN + 1, "BAHUYANG", 8); /* 9:ssid length */
    if (rc != EOK) {
        printf("%s %d \r\n", __FILE__, __LINE__);
        return -1;
    }

    /*
     * OPEN mode
     * for WPA2-PSK mode:
     * set assoc_req.auth as HI_WIFI_SECURITY_WPA2PSK,
     * then memcpy(assoc_req.key, "12345678", 8).
     */
    //热点加密方式
    assoc_req.auth = HI_WIFI_SECURITY_WPA2PSK;

    /* 热点密码 */
    memcpy(assoc_req.key, "123456789", 9);


    ret = hi_wifi_sta_connect(&assoc_req);
    if (ret != HISI_OK) {
        printf("%s %d \r\n", __FILE__, __LINE__);
        return -1;
    }
    printf("%s %d \r\n", __FILE__, __LINE__);
    return 0;
}

int hi_wifi_start_sta(void)
{
    int ret;
    char ifname[WIFI_IFNAME_MAX_SIZE + 1] = {0};
    int len = sizeof(ifname);
    const unsigned char wifi_vap_res_num = APP_INIT_VAP_NUM;
    const unsigned char wifi_user_res_num = APP_INIT_USR_NUM;

    printf("%s %d \r\n", __FILE__, __LINE__);

    ret = hi_wifi_init(wifi_vap_res_num, wifi_user_res_num);
    if (ret != HISI_OK) {
        printf("%s %d \r\n", __FILE__, __LINE__);
        //return -1;
    }

    printf("%s %d \r\n", __FILE__, __LINE__);
    ret = hi_wifi_sta_start(ifname, &len);
    if (ret != HISI_OK) {
        printf("%s %d \r\n", __FILE__, __LINE__);
        return -1;
    }

    /* register call back function to receive wifi event, etc scan results event,
     * connected event, disconnected event.
     */
    ret = hi_wifi_register_event_callback(wifi_wpa_event_cb);
    if (ret != HISI_OK) {
        printf("register wifi event callback failed\n");
    }

    /* acquire netif for IP operation */
    g_lwip_netif = netifapi_netif_find(ifname);
    if (g_lwip_netif == NULL) {
        printf("%s: get netif failed\n", __FUNCTION__);
        return -1;
    }

    /* if received scan results, select one SSID to connect */
    ret = hi_wifi_start_connect();
    if (ret != 0) {
        printf("%s %d \r\n", __FILE__, __LINE__);
        return -1;
    }


    return 0;
}

void hi_wifi_stop_sta(void)
{
    int ret;

    ret = hi_wifi_sta_stop();
    if (ret != HISI_OK) {
        printf("failed to stop sta\n");
    }

    ret = hi_wifi_deinit();
    if (ret != HISI_OK) {
        printf("failed to deinit wifi\n");
    }

    g_lwip_netif = NULL;

    
}



void mqtt_test_thread(void * argv)
{

    argv = argv;

    hi_wifi_start_sta();

    while(start_wifi_connected_flg == 0)
    {
        usleep(300000);
    }

    sleep(3);
    LED_test();

}


void led_off(void)
{
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 1);
}

void led_on(void)
{
    GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_9, 0);
}


void StaExampleEntry(void)
{
    osThreadAttr_t attr;

    attr.name = "wifi_config_thread";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 4096;
    attr.priority = 36;

    if (osThreadNew((osThreadFunc_t)mqtt_test_thread, NULL, &attr) == NULL) {
        printf("[LedExample] Falied to create LedTask!\n");
    }
}

SYS_RUN(StaExampleEntry);

接收UDP数据

程序流程如下:

  1. 创建一个UDP socket句柄,以及一个变量toAd的人,并设置服务器的IP地址和端口号
  2. 使用sendto()函数向服务器发送数据
  3. 使用recvfrom()函数从服务器接受消息
  4. 使用close()函数关闭此socket
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
char recvline[1024];
void udp_thread(void *pdata)
{
    int ret;
    struct sockaddr_in servaddr;
    cJSON *recvjson;
    pdata = pdata;
    int sockfd = socket(PF_INET, SOCK_DGRAM, 0);
    //服务器 ip port
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(50001);
    printf("udp_thread \r\n");
    bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    while(1)
    {
        struct sockaddr_in addrClient;
        int sizeClientAddr = sizeof(struct sockaddr_in);
        memset(recvline, sizeof(recvline), 0);
        ret = recvfrom(sockfd, recvline, 1024, 0, (struct sockaddr*)&addrClient,(socklen_t*)&sizeClientAddr);
        if(ret>0)
        {
            char *pClientIP =inet_ntoa(addrClient.sin_addr);
            printf("%s-%d(%d) says:%s\n",pClientIP,ntohs(addrClient.sin_port),addrClient.sin_port, recvline);
            //进行json解析
            recvjson = cJSON_Parse(recvline);
            if(recvjson != NULL)
            {
                if(cJSON_GetObjectItem(recvjson, "cmd")->valuestring != NULL)
                {
                    printf("cmd : %s\r\n", cJSON_GetObjectItem(recvjson, "cmd")->valuestring);
                    if(strcmp("RED", cJSON_GetObjectItem(recvjson, "cmd")->valuestring) == 0)
                    {
                        set_LED_status(LED_STATUS_RED);
                        printf("RED\r\n");
                    }
                    if(strcmp("YELLOW", cJSON_GetObjectItem(recvjson, "cmd")->valuestring) == 0)
                    {
                        set_LED_status(LED_STATUS_YELLOW);
                        printf("YELLOW\r\n");
                    }
                    if(strcmp("GREEN", cJSON_GetObjectItem(recvjson, "cmd")->valuestring) == 0)
                    {
                        set_LED_status(LED_STATUS_GREEN);
                        printf("GREEN\r\n");
                    }
                    if(strcmp("CLOSE", cJSON_GetObjectItem(recvjson, "cmd")->valuestring) == 0)
                    {
                        set_LED_status(LED_STATUS_CLOSE);
                        printf("CLOSE\r\n");
                    }
                }             
                cJSON_Delete(recvjson);
            }
    }
    }
}
void start_udp_thread(void)
{
    osThreadAttr_t attr;
    attr.name = "wifi_config_thread";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = 2048;
    attr.priority = 36;
    if (osThreadNew((osThreadFunc_t)udp_thread, NULL, &attr) == NULL) {
        printf("[LedExample] Falied to create LedTask!\n");
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 物联网知识 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
Flea框架,一款小巧易用的Java应用基础开发框架 https://github.com/huazie/flea-framework 欢迎各位 star
Flea框架,一款小巧易用的Java应用基础开发框架 https://github.com/huazie/flea-framework 欢迎各位 star
回复回复点赞举报
推荐阅读
php7今天发布正式版!!看鸟哥怎么说的
php7终于来了,本号1个月前就已经编译了RC版本,体验了一番新特性,除了兴奋,也转发一下鸟哥昨天在他公众号发表的一片文章《写在php7发布之际的一些话》,来帮鸟哥和phper们造势。
后端技术探索
2018/08/09
4790
VMware Workstation PRO_v17.0.0_正式版
威睿虚拟机软件VMware Workstation 17 PRO 正式版发布.VMware17最新版增加了全新暗色界面,支持最新Win和Linux客户机系统版本,进了WDDM 1.2和OpenGL 4.3 3D硬件加速支持,12.0版本之后专门为Win10兼容性和功能做了优化,新技术支持DX10,4K高分辨率显示屏,OpenGL 3.3,7.1声道及兼容主流新硬件设备。
张旭博客
2022/12/27
1.3K0
VMware Workstation PRO_v17.0.0_正式版
Z-BlogPHP 1.7 Tenet 正式版发布了,快看看更新了什么内容
本次的版本代号为“Tenet”,出自去年一部烧脑的电影,意为「信条」。没错,我们精心打磨的 ZBP 也有着他的使命,时代也赋予了他更大的任务,我们坚持16年开发维护,是为了使命而坚持,为信念而坚持。
李洋博客
2023/03/03
4280
Z-BlogPHP 1.7 Tenet 正式版发布了,快看看更新了什么内容
Lsky Pro兰空图床2.0正式版发布了!-星泽V社
Lsky Pro 是一个用于在线上传、管理图片的图床程序,中文名:兰空图床,你可以将它作为自己的云上相册,亦可以当作你的写作贴图库。 兰空图床始于 2017 年 10 月,最早的版本由 ThinkPHP 5 开发,后又经历了数个版本的迭代,在 2021 年末启动了新的重写计划并于 2022 年 3 月份发布全新的 2.0 版本。
星泽V社
2022/03/29
1.5K0
Lsky Pro兰空图床2.0正式版发布了!-星泽V社
.NET 7 RC 2 发布,倒计时一个月发布正式版
微软2022-10-12 发布了 .NET 7 RC 2,下一站是.NET 7正式发布,就在下个月Net Conf 2022(11月8日)期间正式发布。 经过长达一年时间的开发,.NET 7 规划的所有主要的新功能都已推出,接下来一个月,努力修复issue,提高稳定性和可靠性。
张善友
2022/10/28
6250
.NET 7 RC 2 发布,倒计时一个月发布正式版
React18正式版发布,未来发展趋势是?
从v16开始,React团队就在普及并发的概念。在v18的迭代过程中(alpha、Beta、RC),也一直在科普并发特性,所以正式版发布时,已经没有什么新鲜特性。
公众号@魔术师卡颂
2022/04/18
6550
《美国联邦政府零信任战略》正式版发布
2022年1月26日,美国管理和预算办公室(OMB)发布《联邦政府零信任战略》(Federal Zero Trust Strategy)正式版。这是继2021年9月7日发布《联邦政府零信任战略》草案之后的重要进展。
网络安全观
2022/03/31
9990
《美国联邦政府零信任战略》正式版发布
微软发布了Visual Studio 2022 RC版,并将在11月8日发布正式版
微软今天发布了Visual Studio 2022 最接近正式发布的RC版本,同时宣布在11月8日发布正式版,届时将在线上发布虚拟的发布活动,具体参见:https://devblogs.microsoft.com/visualstudio/join-us-november-8th-for-the-launch-of-visual-studio-2022/。
张善友
2021/10/18
8120
【Google Play】正式版上架流程 ( 创建版本 | 设置国家地区 | 发布正式版 )
【Google Play】创建 Google 开发者账号 ( 注册邮箱账号 | 创建开发者账号 ) 【Google Play】创建并设置应用 ( 访问权限 | 内容分级 | 受众群体 | 类别及联系方式 | 商品详情 )
韩曙亮
2023/03/29
5.8K1
【Google Play】正式版上架流程 ( 创建版本 | 设置国家地区 | 发布正式版 )
Layui 2.8.0 正式发布,官网全新文档站朴实归来
  两年前 Layui 官网宣布了下线声明,说实话当时内心确实感慨万千毕竟这个免费为我们后端程序员提供的一个前端快熟开发框架的官网就这样下线了确实十分的惋惜,但是庆幸的是官网的下线,只是单纯一个网站自身生命周期的结束,它并不意味着 Layui 这样一个开源项目的停更,Layui 仍然在 Github 和 Gitee 保持活跃,并不存在所谓的停止更新,甚至从 2.6.9 一直迭代到今天的最新版本。两年来,Layui 始终处于没有中心文档的窘迫境地,虽然也一度以 Gitee Pages 为文档的承载,但似乎很难形成一个焦点和归属感。随着 2.8.0 正式版本的发布,它所包含的上百项的内容更新,使得全新的文档站呼之欲出。Layui 新官网于 2023年4月 Layui 2.8.0 正式发布,全新文档站朴实归来。
追逐时光者
2023/05/26
1.9K0
Layui 2.8.0 正式发布,官网全新文档站朴实归来
TVM 中文站正式上线!最全机器学习模型部署「参考书」它来了
内容一览:近日,由 MLC 社区志愿者共同翻译校对的 TVM 中文文档正式发布,现已托管至超神经官网 Hyper.AI。
HyperAI超神经
2022/11/29
8900
TVM 中文站正式上线!最全机器学习模型部署「参考书」它来了
亚马逊AWS 进军 WAN 市场:发布 AWS Cloud WAN 正式版
2022年7月14日,AWS宣布推出AWS Cloud WAN的正式版,这是一种新的托管服务,可连接本地数据中心、托管设施、分支机构和AWS云区域,以简化全球网络的运营。 借助AWS Cloud WAN,企业可以使用中央管理仪表板来定义网络配置、查看全球网络的运行状况,并自动执行日常配置和安全任务。 这家云巨头于2021年12月在拉斯维加斯举行的AWS re:Invent大会上首次介绍了AWS Cloud WAN。 AWS已经在帮助企业使用Amazon Virtual Private Cloud、AWS
云头条
2022/07/19
4340
亚马逊AWS 进军 WAN 市场:发布 AWS Cloud WAN 正式版
PyTorch 1.0 正式版发布了!
作者:ZACH DEVITO、YANGQING JIA、DMYTRO DZHULGAKOV、SOUMITH CHINTALA、JOSEPH SPISAK
机器之心
2018/12/25
5030
PyTorch 1.0 正式版发布了!
Copilot免费时代结束!正式版67元/月,学生党和热门开源项目维护者可白嫖
梦晨 发自 凹非寺 量子位 | 公众号 QbitAI 敲代码神器、程序员的AI助手GitHub Copilot,结束内测正式对所有人开放! 正式版定价10美元/月(人民币约67元),年付有优惠100美元/年(人民币约669元) 从现在起无需排队可申请2个月免费试用,另外对认证学生和热门开源项目维护者免费。 看到这我当场就买了两份。 分别试验了银联+Visa双币信用卡,和通过Paypal使用国内银行借记卡,都能顺利支付。 成功购买后就可以到你喜欢的工具里去安装使用了,目前仅支持VS Code、Visual
量子位
2022/06/24
3.3K0
Copilot免费时代结束!正式版67元/月,学生党和热门开源项目维护者可白嫖
Layui 2.8.0 正式发布,官网全新文档站朴实归来
两年前 Layui 官网宣布了下线声明,说实话当时内心确实感慨万千毕竟这个免费为我们后端程序员提供的一个前端快熟开发框架的官网就这样下线了确实十分的惋惜,但是庆幸的是官网的下线,只是单纯一个网站自身生命周期的结束,它并不意味着 Layui 这样一个开源项目的停更,Layui 仍然在 Github 和 Gitee 保持活跃,并不存在所谓的停止更新,甚至从 2.6.9 一直迭代到今天的最新版本。两年来,Layui 始终处于没有中心文档的窘迫境地,虽然也一度以 Gitee Pages 为文档的承载,但似乎很难形成一个焦点和归属感。随着 2.8.0 正式版本的发布,它所包含的上百项的内容更新,使得全新的文档站呼之欲出。Layui 新官网于 2023年4月 Layui 2.8.0 正式发布,全新文档站朴实归来。
追逐时光者
2023/05/20
1.3K0
Vue 2.0 正式发布了!
今天我非常兴奋的宣布正式发布 Vue.js 2.0:Ghost in the Shell。历经 8 个 alpha 版本、8 个 beta 版本和 8 个 rc 版本 (矮油好巧!),Vue.js 2.0 已经为生产环境准备好了!我们的官方教程 vuejs.org/guide 也已经全面更新。 2.0 的工作自今年 4 月启动以来,核心团队为 API 设计、bugfix、文档、类型声明做出了很重要的贡献,社区中的同学们也反馈了很多有价值的 API 建议——在此为每一位参与者致以大大的感谢! 2.0 有哪些
时见疏星
2018/06/01
1.1K0
tep1.0.0正式版发布且将不再维护
根据pypistats统计,tep在pypi的下载量达到了1w,对于纯个人研发的一款测试小工具来说,已经算不错了,要知道HttpRunner也才6w啊。tep可以说是我在接口自动化测试这个领域的技术沉淀,凝结了个人经验和所见所闻的精华之作,它基于Pytest,借鉴了JMeter、RobotFramework、HttpRunner、京东接口测试平台等各种优秀自动化设计思想,小小工具,蕴含大大能量。相信它也已经影响了不少人,让初学者知道Pytest该怎么玩,让入门者知道Pytest工程化是什么样子,让熟练者可以参考对照优化代码。然而当我把tep优化到1.0.0正式版以后,为什么却选择停止维护呢? 一、 小工具的表达力不够。当我试图用tep来描绘更多自动化设计思想时,瞬间感觉到了一丝苍白,我不一定讲的清楚,别人也不一定能够理解,用代码来交流始终存在着一定门槛。二、每个人对Pytest使用方式不同 。Pytest本身是测试框架,很多人用它来做二次开发,设计”测试框架“,有好的,有差的,不管白猫黑猫能逮到耗子就是好猫,不管设计的如何,能实现接口自动化项目落地就是好框架。tep要想在这个方向上,建立一套标准,几乎是不可能的。这不并意味我会就此放弃Pytest,相反,我将致力于Pytest平台化,从做小工具改为做测试平台。 测试平台具有非常直观的强大表现力,并且具有工程化的规范性,一看就懂,一用就会,一点就通。测试平台也是能更好的做技术沉淀的,如果说写小工具是玩玩而已,那么开发测试平台就是认真搞技术了。比如,如何提高Pytest并行执行的效率,我相信测试平台会比小工具,更能给出一个比较完整的解决方案。下次使用Pytest,也许就不是从tep startproject开始了,而是docker run。
dongfanger
2022/12/31
8530
tep1.0.0正式版发布且将不再维护
《.NET 5.0 背锅案》第1集:验证 .NET 5.0 正式版 docker 镜像问题
今天我们分析了博客站点的2次故障(故障一、故障二),发现一个巧合的地方,.NET 5.0 正式版的 docker 镜像是在11月10日提前发布上线的。
huofo
2022/03/17
4640
《.NET 5.0 背锅案》第1集:验证 .NET 5.0 正式版 docker 镜像问题
正式版即将到来 | Android 12 Beta 5 现已发布
距离 Android 12 的正式发布只有几周时间了!新版 Android 系统的润色已经进入收尾阶段,今天我们带来最后一个 Beta 版更新,供大家进行测试和开发。对于开发者来说,是时候让自己的应用做好准备了!
Android 开发者
2022/03/09
5240
正式版即将到来 | Android 12 Beta 5 现已发布
SuperEdge v0.6.0 版本正式发布
SuperEdge 开发者团队 SuperEdge 是基于原生 Kubernetes 的分布式边缘云容器管理系统,由腾讯云牵头,联合英特尔、VMware 威睿、虎牙、寒武纪、美团、首都在线等多家厂商在2020年12月共同发起的边缘计算开源项目,旨在将把 Kubernetes 强大的容器管理能力无缝的扩展到边缘计算和分布式资源管理的场景中,为边缘 IoT,边缘 AI,边缘智慧行业等赋能,推动物联网和数字化的落地。目前已经成为 CNCF Sandbox 项目,由 CNCF 基金会进行托管。 SuperEdge
腾讯云原生
2021/10/15
4450
推荐阅读
相关推荐
php7今天发布正式版!!看鸟哥怎么说的
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档