当前位置: 首页 > news >正文

【Harmony】端云一体化(云函数)

一、云函数的概述

1、什么是云函数

  • 官方解释

云函数是一项Serverless计算服务,提供FaaS(Function as a Service)能力,一方面云函数将开发测试的对象聚焦到函数级别,可以帮助您大幅简化应用开发与运维相关的事务,另一方面您可以通过在应用中集成云函数SDK,便捷操作云数据库、云存储等,提升业务功能构建的便利性。云函数可以根据函数的实际流量对函数进行弹性伸缩,您无需对服务器资源进行管理,解决了开发者运维管理的难题。

  • 通俗理解

云函数是一种无需管理服务器的计算服务,可以让你只专注于编写函数代码,不需要处理服务器的复杂管理。通过云函数,你可以轻松连接云数据库和云存储,方便地构建应用功能。而且,它会根据你应用的访问量自动调整资源,不用你手动管理服务器资源,让你更专注于开发应用本身。

补充:什么是Serverless?

Serverless 是一种无需管理服务器和运行环境的计算服务。你可以把它想象成一种按需的云计算资源,就像打开水龙头就有水一样,你只需要调用API,云服务就会为你分配所需的计算资源,而无需提前准备服务器或部署应用。Serverless服务实现了计算资源的按需分配,简化了应用的部署和维护,使得开发者可以更加专注于业务逻辑的开发。

2、云函数作用

  • 简化开发与运维

    云函数提供了高效可靠的函数开发与运行框架,替开发者完全解决传统应用开发与运维中的诸多复杂事务(如服务器配置与管理、代码部署、负载均衡、弹性伸缩、高可用保证等等),您只需聚焦业务逻辑、开发并上传函数代码,即可构建高可用、可伸缩的Serverless应用。

  • 扩展周边服务

    云函数作为Serverless的核心与枢纽,支持方便连接和扩展周边云服务能力,您可以像拼搭积木一样自由便捷地组织各项服务来实现业务逻辑。

3、云函数工作原理

在这里插入图片描述

该图片展示了鸿蒙端云一体化的工作原理。从左到右,上到下,我们可以看到以下主要组件和它们之间的关系:
  1. 开发云函数:这表示开发者可以在本地或云端环境中编写和部署函数。这些函数可以通过SDK(软件开发工具包)被集成到各种应用程序中,如移动端、桌面端等。

  2. 函数仓库:这是一个存储和管理函数的地方,开发者可以将他们编写的函数上传到这里。

  3. 触发器类型:当特定事件发生时,会触发函数的执行。例如,可以通过HTTP请求、消息队列、定时器等方式触发函数。

  4. 云函数:这是运行在云端的服务,可以自动伸缩以应对高并发请求。开发者发布的函数会被部署到云函数上,供全球用户访问。

  5. 函数运行平台:这是一个为函数提供运行环境的平台,包括认证服务、云数据库和HTTP网关等功能。

  6. 函数A、B、C:这些都是开发者发布的具体函数,每个函数都可以有自己的功能和用途。

  7. HTTP网关:这是一个对外接口,允许外部客户端通过HTTP协议调用函数。

整个流程如下:开发者首先在本地或云端环境中开发函数,然后将其上传到函数仓库。之后,这些函数可以通过不同的触发器类型被触发,并在云函数上执行。执行结果可以通过函数运行平台的API返回给调用者。
鸿蒙端云一体化的这种架构使得开发者可以更专注于函数的开发,而无需关心底层的基础设施。同时,它也提供了高度的可扩展性和灵活性,使应用能够轻松应对各种业务需求的变化。

二、云函数开发准备

1、创建项目(如果已创建直接进入第二步)

1)登录,点击“我的项目”。

AGC平台地址
在这里插入图片描述

如果大家第一次点击我的项目,会出现以下同意协议,后续出现类似的,同意或者确定。

2)在项目页面中点击“添加项目”。

3)在“创建项目”页面中输入项目名称后 ,点击“创建并继续”。

说明:

点击“创建并继续”后,如果系统提示“您所在团队创建的项目数已经达到上限,请清理不需要的项目”,请进入“我的项目”,点击需要删除的项目卡片,点击“项目设置”页面下方的“删除项目”清理多余的项目。

2、添加应用(已经添加直接进入第三步)

如果已经创建了项目,可以使用已经创建的项目,如果不想使用已经创建的项目,则可以自己重新按照上一个小节创建AGC项目

  1. 若项目中没有应用,在“项目设置”页面中点击“添加应用”。

    若项目中已有应用,展开顶部应用列表框,点击“添加应用”。

    添加应用页面设置参数

    第一步:选择APP(HarmonyOS)

在这里插入图片描述

第2步:选择APPID进行参数设置,点击下一步

在这里插入图片描述

下一步选择,项目,这里是默认的就好,因为我是通过项目来创建应用的,直接点击确认

在这里插入图片描述

说明:

如果提示“包名已存在,请更换包名”,您需要检查下您是否已经创建相同包名的应用,如果有,请勿重复创建。如果您未创建,请联系华为技术支持人员进行处理。

3、开通服务

  1. 登录AppGallery Connect,点击“我的项目”。
  2. 在项目列表中点击需要开通云函数的项目。
    3. 在左侧导航栏选择“云开发(Serverless)> 云函数”,进入云函数页面,点击“立即开通”。

在这里插入图片描述

三、开发云函数(服务端编写+客户端调用)

1、案例01:简单计算案例

需求:实现用于计算两个数的值 之和的云函数

在这里插入图片描述

实现思路

1、服务器端创建云函数

2、服务器端测试云函数是否正常运行通过

3、编写客户端的代码来调用云函数

4、运行测试

实现步骤

第一步:服务器端创建云函数

新建一个函数名名为fun0901的函数名

点击创建

在这里插入图片描述

函数配置、点击下一步

在这里插入图片描述

触发器的选择,这里默认就够了

在这里插入图片描述

编辑函数代码

在这里插入图片描述

放大以后,编写代码,默认模版,我们可以在里面进行编辑,圈红的地方都不要动

在这里插入图片描述

编辑函数代码,函数的功能就是获取两个数,然后再进行相加,然后将相加的结果返回,代码编辑好了以后,缩小编辑区域,进入下一步

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

第二步:测试

完成以后,点击测试,运行函数

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

第三步:客户端调用
(1)创建项目

注意bundle name要和云侧项目的包名一致

(2)下载sdk配置文件 agconnect-services.json

将下载的json文件复制到src/main/resources/rawfile目录中

(3)配置oh-package.json5

entry\oh-package.json5

鸿蒙操作系统中的oh-package.json5文件是用于配置鸿蒙应用的元数据文件,类似于Node.js中的package.json。这个文件定义了鸿蒙应用的名称、版本、描述、主要入口文件、作者、许可证以及依赖关系等信息。json5是JSON的一个扩展,它允许在文件中使用注释和更为宽松的语法。记得点sync

  "dependencies": {
    "@hw-agconnect/crypto-ohos": "^1.0.10",
    "@hw-agconnect/function-ohos": "^1.0.10",
    "@hw-agconnect/auth-ohos": "^1.0.10",
    "@hw-agconnect/cloudstorage-ohos": "^1.0.10",
    "@hw-agconnect/api-ohos": "^1.0.10",
    "@hw-agconnect/base-ohos": "^1.0.10",
    "@hw-agconnect/core-ohos": "^1.0.10",
    "@hw-agconnect/credential-ohos": "^1.0.10",
    "@ohos/agconnect-auth-component": "^1.0.5",
    "@hw-agconnect/auth-component": "^1.0.0",
    "@hw-agconnect/cloud": "^1.0.0",
    "@hw-agconnect/hmcore": "^1.0.0",
    "long": "5.2.1"
  }
(4)加入网络权限

src/main/module.json5

 "requestPermissions": [
      {"name": 'ohos.permission.INTERNET'}
    ],
(5)修改.so文件的加载顺序

entry/build-profile.json5

...
"buildOption": {
    //配置筛选har依赖.so资源文件的过滤规则
    "napiLibFilterOption": {
      //按照.so文件的优先级顺序,打包最高优先级的.so文件
      "pickFirsts": [
        "**/1.so"
      ],
      //按照.so文件的优先级顺序,打包最低优先级的.so 文件
      "pickLasts": [
        "**/2.so"
      ],
      //排除的.so文件
      "excludes": [
        "**/3.so"
      ],
      //允许当.so重名冲突时,使用高优先级的.so文件覆盖低优先级的.so文件
      "enableOverride": true,
    }
  }
...
(6)entryAbility初始化
import { initialize } from '@hw-agconnect/hmcore';
import json from '../../resources/rawfile/agconnect-services.json'
...
 async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
  try {
   await initialize(this.context, json);
   console.info('hmlog-->','AGConnectSuccessed!')
  } catch (e) {
   console.error('hmlog-->','AGConnectError', JSON.stringify(e))
  }
 }
(7) 客户端调用
import cloud from '@hw-agconnect/cloud'
import { FunctionResult } from '@hw-agconnect/function-ohos'

@Entry
@Component
struct Demo01 {
  @State a:number=0 //加数1
  @State b:number=0 //加数2
  @State c:number=0 //结果
  build() {
    Column({space:30}){
      Text("客户端调用云函数(案例一:简单案例)")

      Row({space:15}){
        TextInput({text:""+this.a}).width(80).onChange(val=>this.a=parseInt(val))
        Text("+")
        TextInput({text:""+this.b}).width(80).onChange(val=>this.b=parseInt(val))
        Text("=")
        Text(this.c+"")
      }.width("100%")

      Button("计算").width("60%").onClick(()=>{
        this.callFun()
      })
    }
    .width("100%")
    .padding(30)
  }
  //点击计算按钮的的时候调用云函数
  async callFun(){
    //一般情况下肯定是需要看看输入是否为空,格式对不对
    //以上我们假设做过了
    //调用云函数
    //函数名
    //version 函数的版本 默认版本就是$latest
    let res:FunctionResult=await cloud.callFunction({
      name:"fun0901",
      version:'$latest',
      params:{
        "num1":this.a,
        "num2":this.b
      }
    })
    // this.c = res.getValue()
    // console.log(JSON.stringify(res.getValue())) //{"result":121}
    this.c =  res.getValue().result
    console.log(this.c+"<====")
  }
}

在这里插入图片描述

2、案例02:根据输入的年,获取这个年的生肖

在这里插入图片描述

实现思路

1、服务器端创建云函数

2、服务器端测试云函数是否正常运行通过

3、编写客户端的代码来调用云函数

4、运行测试

实现步骤

第一步:服务器端创建云函数

新建一个函数名名为fun0902的函数名,其他操作和上面案例01一致(参考上面),函数内容如下

// handler.js is a demo for handler function.
let myHandler = function(event, context, callback, logger) {
    let res = new context.HTTPResponse({"simple": "example"}, {
        "res-type": "simple example",
        "faas-content-type": "json"
    }, "application/json", "200");
  
  
    //声明一个变量year,用于接受传递过来的参数
    let year;
    //如果body中有数据,那就是客户端调用传递过来的参数
    if(event.body){
    	//获取传递过来的参数
    	year = JSON.parse(event.body).year
    }else{
    	//如果是服务端调用当前的函数,那就直接通过event.year获取
    	year = event.year
    }
    //将year对12求余
	//
	function isNumber(input){
      logger.info(parseInt(input).toString())
      if(parseInt(input).toString()=='NaN'){
        return false
      }else{
        return true
      }
    }
  
  	//自己封装的方法
  	function animal(inputyear){
      let shengxiao ="" //这个变量用于保存具体的生效
      if(!isNumber(inputyear)){
        shengxiao="please input a number"
      }else{
        let yu=year%12
        switch(yu){
          case 0: 
          	shengxiao='猴'
          	break
          case 1: 
          	shengxiao='鸡'
          	break
          case 2: 
          	shengxiao='狗'
          	break
          case 3: 
          	shengxiao='猪'
          	break
          case 4: 
          	shengxiao='鼠'
          	break
          case 5: 
          	shengxiao='牛'
          	break
          case 6: 
          	shengxiao='虎'
          	break
          case 7: 
          	shengxiao='兔'
          	break
          case 8: 
          	shengxiao='龙'
          	break
          case 9: 
          	shengxiao='蛇'
          	break
          case 10: 
          	shengxiao='马'
          	break
          case 11: 
          	shengxiao='羊'
          	break
        }
      }
      
      return shengxiao;
    }
  	//给调用者响应
     res.body = {result:animal(year)}

    // send response
    callback(res);
};

module.exports.myHandler = myHandler;

客户端调用
import cloud from '@hw-agconnect/cloud'

@Entry
@Component
struct Demo02 {
  //用于存放年
  @State num:number=0

  @State shengxiao:string = "" //用于查询生效的结果
  build() {
    Column({space:15}){
      Text("客户端调用云函数(案例二:复杂点的示例)")

      TextInput().onChange(val=>this.num=Number(val))
      Button("查询生效").width("100%").onClick(()=>{
        this.getShengXiao()
      })
      Text("生肖:"+this.shengxiao)
    }
    .width("100%")
    .height("100%")
    .padding(30)
  }

  async getShengXiao(){
    try {
      let rs = await cloud.callFunction({
        name:"fun0902",
        version:"$latest",
        params:{
          year:this.num
        }
      })

      this.shengxiao = rs.getValue().result

    }catch (e) {
      console.log("====>error:",JSON.stringify(e))
    }
  }
}

四、开发云函数(使用端云一体化的方式)

案例01:简单的计算案例

1、创建项目、选择CloudDev,然后点击下一步

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

云侧项目,找到云函数(cloudfunctions)右击,new Cloud Function在这里插入图片描述

在这里插入图片描述

创建好了的默认内容

右击函数,执行run在这里插入图片描述

dev中,将函数测试好了没有问题,后续再传到云端

在这里插入图片描述

到此云侧函数创建好了,但是还没有实现具体的功能,要实现具体的功能,写代码调试,最后再上传到 云侧就可以

在dev中书写的云侧的代码,并测试成功

let myHandler = async function (event, context, callback, logger) {
  logger.info(event);

  // do something here
  let num1:number = 0
  let num2:number = 0
  //如果是客户端调用
  if(event.body){
    let _body = JSON.parse(event.body)
    num1 = _body.num1
    num2 = _body.num2
  }else{
    //如果是服务器端调用就执行这个
    num1 = event.num1
    num2 = event.num2
  }

  let sum =  num1+num2

  callback({
    code: 0,
    desc: "Success.",
    body:{
      result:sum
    }
  });
};

export { myHandler };

在这里插入图片描述

下一步就将我们的在一体化项目中创建的云函数发布的云服务上去

在这里插入图片描述

上传到云函数成功了。

在这里插入图片描述

在这里插入图片描述

客户端,调用云函数

客户端可以使用这个端云一体化的项目(端侧)调用云函数,端侧项目没有rawfile目录,需要自己创建。另外还需配置依赖so文件加载顺序。。。。都需要再做

节约时间,我个人直接使用原来的不是端云一体化的项目进行访问了,这个功能和前面一样。

import cloud from '@hw-agconnect/cloud'
import { FunctionResult } from '@hw-agconnect/function-ohos'

@Entry
@Component
struct Demo03 {
  @State a:number=0 //加数1
  @State b:number=0 //加数2
  @State c:number=0 //结果
  build() {
    Column({space:30}){
      Text("客户端调用云函数(端云一体化创建的云函数)")

      Row({space:15}){
        TextInput({text:""+this.a}).width(80).onChange(val=>{
          this.a=Number(val) //针对""转换为0 但是parseInt 针对空字符转成NaN
        })
        Text("+")
        TextInput({text:""+this.b}).width(80).onChange(val=>this.b=Number(val))
        Text("=")
        Text(this.c+"")
      }.width("100%")

      Button("计算").width("60%").onClick(()=>{
        this.callFun()
      })
    }
    .width("100%")
    .padding(30)
  }
  //点击计算按钮的的时候调用云函数
  async callFun(){
    //一般情况下肯定是需要看看输入是否为空,格式对不对
    //以上我们假设做过了
    //调用云函数
    //函数名
    //version 函数的版本 默认版本就是$latest
    let res:FunctionResult=await cloud.callFunction({
      name:"fun0903",
      version:'$latest',
      params:{
        "num1":this.a,
        "num2":this.b
      }
    })
    // this.c = res.getValue()
    // console.log(JSON.stringify(res.getValue())) //{"result":121}
    console.log("====>",JSON.stringify(res.getValue())) //注意端云一体化云函数返回的内容
    this.c = res.getValue().body.result
  }
}

案例02:输入数值获取生效案例

1、云开发本地开发云函数

let myHandler = async function (event, context, callback, logger) {

  /**
   * 根据输入的一个年份 获取生效
   * @param input 输入的年份
   */
  function getZodiac(input){
    let mo:number = input%12
    let zodiac=""
    switch (mo){
      case 0:
        zodiac="猴"
        break
      case 1:
        zodiac="鸡"
        break
      case 2:
        zodiac="狗"
        break
      case 3:
        zodiac="猪"
        break
      case 4:
        zodiac="鼠"
        break
      case 5:
        zodiac="牛"
        break
      case 6:
        zodiac="虎"
        break
      case 7:
        zodiac="兔"
        break
      case 8:
        zodiac="龙"
        break
      case 9:
        zodiac="蛇"
        break
      case 10:
        zodiac="马"
        break
      case 11:
        zodiac="羊"
        break
      default :
        zodiac="请输入数值"
      break
    }
    return zodiac
  }

  let year
  if(event.body){
      year=JSON.parse(event.body).year
  }else{
    year=event.year
  }
  //如果year的类型是字符串类型的话 返回请输入数字
  if(typeof(year)=='string'){
    callback({
      result:"对不起请输入数字"
    });
  }else{
    //否则就正常返回生肖的内容
    callback({
      result:getZodiac(year)
    })
  }
};

export { myHandler };

2、端侧调用发布到云侧的代码

import cloud from '@hw-agconnect/cloud'

@Entry
@Component
struct Demo04 {
  //用于存放年
  @State num:number=0

  @State shengxiao:string = "" //用于查询生效的结果
  build() {
    Column({space:15}){
      Text("客户端调用云函数2(端云一体化上传的)")

      TextInput().onChange(val=>{
        if(Number(val).toString()=="NaN"){
          this.num = -1
        }else{
          this.num = Number(val)
        }

      })
      Button("查询生效").width("100%").onClick(()=>{
        this.getShengXiao()
      })
      Text("生肖:"+this.shengxiao)
    }
    .width("100%")
    .height("100%")
    .padding(30)
  }

  async getShengXiao(){
    try {
      let rs = await cloud.callFunction({
        name:"fun0904",
        version:"$latest",
        params:{
          year:this.num
        }
      })

      this.shengxiao = rs.getValue().result

    }catch (e) {
      console.log("====>error:",JSON.stringify(e))
    }
  }
}

相关文章:

  • 微信能否做门户网站电脑优化大师哪个好
  • 北京装修公司排名十强关键词seo优化
  • 广州建企业网站关于市场营销的培训课程
  • 社交博客网站开发怎样进行seo优化
  • 哪些外贸网站比较好营销方法有哪些方式
  • 有利于优化的网站模板自己做网站建设
  • Linux vagrant 导入Centos到virtualbox
  • 重构谷粒商城11:node快速入门
  • linux命令五
  • 三分钟知识点:Spring事务的传播机制
  • Python基础知识点(类和对象)
  • 初识MySQL · 复合查询(内外连接)
  • uniapp开发微信小程序,根据胶囊按钮来自定义导航栏
  • java InterruptedException
  • 从零开始写android 的智能指针
  • vue watch 和 watchEffect的区别和用法
  • C++:日期类,运算符重载,深浅拷贝问题
  • python:面向对象之包
  • 2025.04.10-拼多多春招笔试第四题
  • MySQL的半同步模式
  • 中间件-消息队列
  • 网络3 子网掩码 划分ip地址
  • h265为什么没有大范围应用
  • C/C++共有的类型转换与c++特有的四种强制类型转换
  • MySQL——存储过程、索引
  • 融智学三大定律:打开人机协同智慧大门的钥匙