首页 > 其他分享 >IoT平台软件:Google Cloud IoT二次开发_RESTfulAPI与gRPC

IoT平台软件:Google Cloud IoT二次开发_RESTfulAPI与gRPC

时间:2024-10-18 22:18:32浏览次数:7  
标签:status name gRPC IoT devices device 二次开发 seen id

RESTful API 与 gRPC

RESTful API 原理

RESTful API 是一种基于 HTTP 协议的架构风格,用于构建分布式系统中的网络应用程序。它通过一组规则和约束来定义客户端和服务器之间的交互方式,使得系统更加简洁、可扩展和易于理解。RESTful API 的设计原则包括:

  1. 无状态性:每个请求都必须包含理解请求所必需的所有信息,服务器不保存任何客户端的上下文信息。

  2. 统一接口:通过一组固定的接口(如 GET、POST、PUT、DELETE)来操作资源。

  3. 资源的表述:资源通过 URI(Uniform Resource Identifier)来标识,并且可以通过请求返回资源的表述(如 JSON、XML)。

  4. 分层系统:客户端和服务器之间可以有中间层,如缓存、负载均衡等。

  5. 按需代码:服务器可以向客户端发送可执行代码,如 JavaScript,以扩展客户端的功能。
    在这里插入图片描述

HTTP 方法

RESTful API 通常使用以下 HTTP 方法来操作资源:

  • GET:用于获取资源。

  • POST:用于创建资源。

  • PUT:用于更新资源。

  • DELETE:用于删除资源。

  • PATCH:用于部分更新资源。

资源标识

资源通过 URI 来标识,通常包括路径和查询参数。例如,假设有一个 IoT 设备管理系统的 API,可以使用以下 URI 来标识设备:

  • GET /devices:获取所有设备。

  • GET /devices/{device_id}:获取指定设备的详细信息。

  • POST /devices:创建新设备。

  • PUT /devices/{device_id}:更新指定设备的信息。

  • DELETE /devices/{device_id}:删除指定设备。

响应状态码

HTTP 状态码用于表示请求的处理结果,常见的状态码包括:

  • 200 OK:成功响应。

  • 201 Created:资源创建成功。

  • 204 No Content:成功响应,但无内容返回。

  • 400 Bad Request:请求无效。

  • 401 Unauthorized:请求未授权。

  • 403 Forbidden:请求被禁止。

  • 404 Not Found:资源未找到。

  • 500 Internal Server Error:服务器内部错误。

内容协商

内容协商是指客户端和服务器之间协商资源的表示形式。客户端可以通过 Accept 头来指定希望接收的媒体类型,服务器通过 Content-Type 头来指定响应的媒体类型。例如:


GET /devices/123 HTTP/1.1

Host: example.com

Accept: application/json

服务器响应:


HTTP/1.1 200 OK

Content-Type: application/json



{

  "device_id": "123",

  "name": "Device 123",

  "status": "online",

  "last_seen": "2023-01-01T00:00:00Z"

}

示例:创建一个简单的 RESTful API

假设我们使用 Flask 框架来创建一个简单的 RESTful API,用于管理 IoT 设备。

首先,安装 Flask:


pip install Flask

然后,创建一个 Flask 应用:


# app.py

from flask import Flask, request, jsonify



app = Flask(__name__)



# 模拟设备数据

devices = {

    "123": {"name": "Device 123", "status": "online", "last_seen": "2023-01-01T00:00:00Z"},

    "456": {"name": "Device 456", "status": "offline", "last_seen": "2023-01-02T12:00:00Z"}

}



@app.route('/devices', methods=['GET'])

def get_devices():

    return jsonify(list(devices.values()))



@app.route('/devices/<device_id>', methods=['GET'])

def get_device(device_id):

    if device_id in devices:

        return jsonify(devices[device_id])

    else:

        return jsonify({"error": "Device not found"}), 404



@app.route('/devices', methods=['POST'])

def create_device():

    data = request.get_json()

    if not data or 'name' not in data:

        return jsonify({"error": "Invalid request"}), 400

    device_id = str(len(devices) + 1)

    devices[device_id] = {

        "name": data['name'],

        "status": "online",

        "last_seen": "2023-01-01T00:00:00Z"

    }

    return jsonify({"device_id": device_id, "message": "Device created"}), 201



@app.route('/devices/<device_id>', methods=['PUT'])

def update_device(device_id):

    data = request.get_json()

    if device_id not in devices:

        return jsonify({"error": "Device not found"}), 404

    if not data or 'name' not in data:

        return jsonify({"error": "Invalid request"}), 400

    devices[device_id]['name'] = data['name']

    devices[device_id]['status'] = data.get('status', 'online')

    devices[device_id]['last_seen'] = data.get('last_seen', '2023-01-01T00:00:00Z')

    return jsonify({"message": "Device updated"})



@app.route('/devices/<device_id>', methods=['DELETE'])

def delete_device(device_id):

    if device_id in devices:

        del devices[device_id]

        return jsonify({"message": "Device deleted"})

    else:

        return jsonify({"error": "Device not found"}), 404



if __name__ == '__main__':

    app.run(debug=True)

运行 Flask 应用:


python app.py

测试 API

可以使用 curl 或 Postman 来测试这个 API。

  • 获取所有设备

curl -X GET http://127.0.0.1:5000/devices

  • 获取指定设备

curl -X GET http://127.0.0.1:5000/devices/123

  • 创建设备

curl -X POST http://127.0.0.1:5000/devices -H "Content-Type: application/json" -d '{"name": "New Device"}'

  • 更新设备

curl -X PUT http://127.0.0.1:5000/devices/123 -H "Content-Type: application/json" -d '{"name": "Updated Device", "status": "offline"}'

  • 删除设备

curl -X DELETE http://127.0.0.1:5000/devices/123

gRPC 原理

gRPC(gRPC Remote Procedure Call)是一种高性能、开源和通用的 RPC 框架,由 Google 开发。它基于 HTTP/2 协议,并使用 Protocol Buffers 作为接口定义语言(IDL)和数据交换格式。gRPC 支持多种语言,包括 Python、Java、C++、Go、Ruby 等,使得不同语言的客户端和服务器可以方便地进行通信。

协议缓冲区(Protocol Buffers)

Protocol Buffers 是一种语言中立、平台中立的结构化数据序列化方法。它用于定义服务接口和消息格式,生成客户端和服务器的代码。Protocol Buffers 的定义文件通常以 .proto 为扩展名。

服务定义

.proto 文件中定义服务接口和消息格式。例如,定义一个 IoT 设备管理服务:


// device.proto

syntax = "proto3";



package device;



service DeviceManager {

  rpc GetDevice (DeviceRequest) returns (DeviceResponse);

  rpc CreateDevice (DeviceRequest) returns (DeviceResponse);

  rpc UpdateDevice (DeviceRequest) returns (DeviceResponse);

  rpc DeleteDevice (DeviceRequest) returns (DeviceResponse);

  rpc ListDevices (ListDevicesRequest) returns (ListDevicesResponse);

}



message DeviceRequest {

  string device_id = 1;

  string name = 2;

  string status = 3;

  string last_seen = 4;

}



message DeviceResponse {

  string device_id = 1;

  string name = 2;

  string status = 3;

  string last_seen = 4;

  string message = 5;

}



message ListDevicesRequest {}



message ListDevicesResponse {

  repeated DeviceResponse devices = 1;

}

生成代码

使用 protoc 编译器生成客户端和服务器的代码。假设我们使用 Python 作为开发语言:


pip install grpcio grpcio-tools

生成 Python 代码:


python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. device.proto

生成的文件包括 device_pb2.pydevice_pb2_grpc.py

服务器端实现

在服务器端实现服务接口。创建一个 server.py 文件:


# server.py

from concurrent import futures

import grpc

import time

import datetime



import device_pb2

import device_pb2_grpc



# 模拟设备数据

devices = {

    "123": {"name": "Device 123", "status": "online", "last_seen": "2023-01-01T00:00:00Z"},

    "456": {"name": "Device 456", "status": "offline", "last_seen": "2023-01-02T12:00:00Z"}

}



class DeviceManagerServicer(device_pb2_grpc.DeviceManagerServicer):

    def GetDevice(self, request, context):

        if request.device_id not in devices:

            context.set_code(grpc.StatusCode.NOT_FOUND)

            context.set_details("Device not found")

            return device_pb2.DeviceResponse()

        device = devices[request.device_id]

        return device_pb2.DeviceResponse(

            device_id=request.device_id,

            name=device['name'],

            status=device['status'],

            last_seen=device['last_seen']

        )



    def CreateDevice(self, request, context):

        if not request.name:

            context.set_code(grpc.StatusCode.INVALID_ARGUMENT)

            context.set_details("Invalid request")

            return device_pb2.DeviceResponse()

        device_id = str(len(devices) + 1)

        devices[device_id] = {

            "name": request.name,

            "status": request.status or "online",

            "last_seen": request.last_seen or datetime.datetime.utcnow().isoformat() + "Z"

        }

        return device_pb2.DeviceResponse(

            device_id=device_id,

            name=devices[device_id]['name'],

            status=devices[device_id]['status'],

            last_seen=devices[device_id]['last_seen'],

            message="Device created"

        )



    def UpdateDevice(self, request, context):

        if request.device_id not in devices:

            context.set_code(grpc.StatusCode.NOT_FOUND)

            context.set_details("Device not found")

            return device_pb2.DeviceResponse()

        if not request.name:

            context.set_code(grpc.StatusCode.INVALID_ARGUMENT)

            context.set_details("Invalid request")

            return device_pb2.DeviceResponse()

        device = devices[request.device_id]

        device['name'] = request.name

        device['status'] = request.status or device['status']

        device['last_seen'] = request.last_seen or device['last_seen']

        return device_pb2.DeviceResponse(

            device_id=request.device_id,

            name=device['name'],

            status=device['status'],

            last_seen=device['last_seen'],

            message="Device updated"

        )



    def DeleteDevice(self, request, context):

        if request.device_id in devices:

            del devices[request.device_id]

            return device_pb2.DeviceResponse(message="Device deleted")

        else:

            context.set_code(grpc.StatusCode.NOT_FOUND)

            context.set_details("Device not found")

            return device_pb2.DeviceResponse()



    def ListDevices(self, request, context):

        device_responses = []

        for device_id, device in devices.items():

            device_responses.append(device_pb2.DeviceResponse(

                device_id=device_id,

                name=device['name'],

                status=device['status'],

                last_seen=device['last_seen']

            ))

        return device_pb2.ListDevicesResponse(devices=device_responses)



def serve():

    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

    device_pb2_grpc.add_DeviceManagerServicer_to_server(DeviceManagerServicer(), server)

    server.add_insecure_port('[::]:50051')

    server.start()

    print("Server started on port 50051")

    try:

        while True:

            time.sleep(86400)

    except KeyboardInterrupt:

        server.stop(0)



if __name__ == '__main__':

    serve()

客户端实现

在客户端实现调用服务的方法。创建一个 client.py 文件:


# client.py

import grpc

import device_pb2

import device_pb2_grpc



def get_device(stub, device_id):

    response = stub.GetDevice(device_pb2.DeviceRequest(device_id=device_id))

    print(f"Device: {response.device_id}, Name: {response.name}, Status: {response.status}, Last Seen: {response.last_seen}")



def create_device(stub, name, status=None, last_seen=None):

    response = stub.CreateDevice(device_pb2.DeviceRequest(name=name, status=status, last_seen=last_seen))

    print(f"Device created: {response.device_id}, Name: {response.name}, Status: {response.status}, Last Seen: {response.last_seen}")



def update_device(stub, device_id, name, status=None, last_seen=None):

    response = stub.UpdateDevice(device_pb2.DeviceRequest(device_id=device_id, name=name, status=status, last_seen=last_seen))

    print(f"Device updated: {response.device_id}, Name: {response.name}, Status: {response.status}, Last Seen: {response.last_seen}")



def delete_device(stub, device_id):

    response = stub.DeleteDevice(device_pb2.DeviceRequest(device_id=device_id))

    print(f"Device deleted: {response.device_id}")



def list_devices(stub):

    response = stub.ListDevices(device_pb2.ListDevicesRequest())

    for device in response.devices:

        print(f"Device: {device.device_id}, Name: {device.name}, Status: {device.status}, Last Seen: {device.last_seen}")



def run():

    channel = grpc.insecure_channel('localhost:50051')

    stub = device_pb2_grpc.DeviceManagerStub(channel)



    print("1. Get device")

    print("2. Create device")

    print("3. Update device")

    print("4. Delete device")

    print("5. List devices")



    choice = input("Choose an option: ")



    if choice == "1":

        device_id = input("Enter device ID: ")

        get_device(stub, device_id)

    elif choice == "2":

        name = input("Enter device name: ")

        status = input("Enter device status (optional): ")

        last_seen = input("Enter last seen time (optional): ")

        create_device(stub, name, status, last_seen)

    elif choice == "3":

        device_id = input("Enter device ID: ")

        name = input("Enter device name: ")

        status = input("Enter device status (optional): ")

        last_seen = input("Enter last seen time (optional): ")

        update_device(stub, device_id, name, status, last_seen)

    elif choice == "4":

        device_id = input("Enter device ID: ")

        delete_device(stub, device_id)

    elif choice == "5":

        list_devices(stub)

    else:

        print("Invalid choice")



if __name__ == '__main__':

    run()

运行和测试

首先运行服务器:


python server.py

然后运行客户端:


python client.py

根据提示选择操作,例如:

  • 获取指定设备

Choose an option: 1

Enter device ID: 123

Device: 123, Name: Device 123, Status: online, Last Seen: 2023-01-01T00:00:00Z

  • 创建设备

Choose an option: 2

Enter device name: New Device

Enter device status (optional): online

Enter last seen time (optional): 2023-01-03T00:00:00Z

Device created: 3, Name: New Device, Status: online, Last Seen: 2023-01-03T00:00:00Z

  • 更新设备

Choose an option: 3

Enter device ID: 123

Enter device name: Updated Device 123

Enter device status (optional): offline

Enter last seen time (optional): 2023-01-04T00:00:00Z

Device updated: 123, Name: Updated Device 123, Status: offline, Last Seen: 2023-01-04T00:00:00Z

  • 删除设备

Choose an option: 4

Enter device ID: 123

Device deleted: 123

  • 获取所有设备

Choose an option: 5

Device: 456, Name: Device 456, Status: offline, Last Seen: 2023-01-02T12:00:00Z

Device: 3, Name: New Device, Status: online, Last Seen: 2023-01-03T00:00:00Z

RESTful API 与 gRPC 的对比

性能

  • RESTful API:基于 HTTP/1.1,性能相对较低,尤其是在大流量和高并发的场景下。HTTP/1.1 协议在每次请求时需要建立和关闭连接,这在高并发情况下会导致较大的性能开销。

  • gRPC:基于 HTTP/2,支持多路复用和二进制编码,性能更高,适合大流量和高并发的场景。HTTP/2 的多路复用特性允许在一个连接上同时处理多个请求,减少了连接的建立和关闭开销。此外,gRPC 使用 Protocol Buffers 作为数据交换格式,二进制编码相比 JSON 或 XML 更紧凑、更高效。

协议

  • RESTful API:使用 HTTP 协议,请求和响应数据通常以 JSON 或 XML 格式表示。HTTP 协议广泛支持,易于理解和调试,适合浏览器和移动应用等客户端。

  • gRPC:使用 HTTP/2 协议,并且数据交换格式为 Protocol Buffers。HTTP/2 提供了更多的高级特性,如流控制、头部压缩和服务器推送,使得 gRPC 在网络传输上更加高效。Protocol Buffers 是一种高效的序列化格式,支持多种编程语言,使得跨语言通信更加方便。

通信方式

  • RESTful API:通常使用请求/响应模式,客户端发送 HTTP 请求到服务器,服务器处理请求并返回响应。这种模式简单直观,适用于大多数 Web 应用。

  • gRPC:支持请求/响应模式、双向流、客户端流和服务器流等多种通信方式。双向流允许客户端和服务器同时发送和接收消息,适用于实时通信和流式数据处理场景。

数据格式

  • RESTful API:数据通常以 JSON 或 XML 格式表示,这些格式易于阅读和调试,但相对冗长且解析效率较低。

  • gRPC:使用 Protocol Buffers 作为数据交换格式,这种格式紧凑且解析效率高,但需要生成代码,对开发者来说学习曲线略高。

安全性

  • RESTful API:通常使用 HTTPS 来保证安全性,支持多种认证方式,如 Basic Auth、OAuth、JWT 等。安全性方面相对成熟,易于实现。

  • gRPC:同样支持 HTTPS,但更倾向于使用 gRPC 的内置认证机制,如 SSL/TLS 证书和 gRPC 认证插件。gRPC 的流控制和头部压缩等特性也有助于提高安全性。

适用场景

  • RESTful API:适用于简单的 Web 应用和移动应用,尤其是当客户端和服务器之间的交互相对简单且请求响应模式足够时。

  • gRPC:适用于需要高性能、低延迟和复杂通信模式的场景,如微服务架构、实时数据流和跨语言通信。

示例:使用 gRPC 和 RESTful API 管理 IoT 设备

RESTful API 示例

我们已经使用 Flask 创建了一个简单的 RESTful API 用于管理 IoT 设备。以下是 Flask 应用的代码:


# app.py

from flask import Flask, request, jsonify



app = Flask(__name__)



# 模拟设备数据

devices = {

    "123": {"name": "Device 123", "status": "online", "last_seen": "2023-01-01T00:00:00Z"},

    "456": {"name": "Device 456", "status": "offline", "last_seen": "2023-01-02T12:00:00Z"}

}



@app.route('/devices', methods=['GET'])

def get_devices():

    return jsonify(list(devices.values()))



@app.route('/devices/<device_id>', methods=['GET'])

def get_device(device_id):

    if device_id in devices:

        return jsonify(devices[device_id])

    else:

        return jsonify({"error": "Device not found"}), 404



@app.route('/devices', methods=['POST'])

def create_device():

    data = request.get_json()

    if not data or 'name' not in data:

        return jsonify({"error": "Invalid request"}), 400

    device_id = str(len(devices) + 1)

    devices[device_id] = {

        "name": data['name'],

        "status": "online",

        "last_seen": "2023-01-01T00:00:00Z"

    }

    return jsonify({"device_id": device_id, "message": "Device created"}), 201



@app.route('/devices/<device_id>', methods=['PUT'])

def update_device(device_id):

    data = request.get_json()

    if device_id not in devices:

        return jsonify({"error": "Device not found"}), 404

    if not data or 'name' not in data:

        return jsonify({"error": "Invalid request"}), 400

    devices[device_id]['name'] = data['name']

    devices[device_id]['status'] = data.get('status', 'online')

    devices[device_id]['last_seen'] = data.get('last_seen', '2023-01-01T00:00:00Z')

    return jsonify({"message": "Device updated"})



@app.route('/devices/<device_id>', methods=['DELETE'])

def delete_device(device_id):

    if device_id in devices:

        del devices[device_id]

        return jsonify({"message": "Device deleted"})

    else:

        return jsonify({"error": "Device not found"}), 404



if __name__ == '__main__':

    app.run(debug=True)

gRPC 示例

我们已经使用 gRPC 创建了一个简单的服务,用于管理 IoT 设备。以下是服务器端和客户端的代码:

服务器端实现

# server.py

from concurrent import futures

import grpc

import time

import datetime



import device_pb2

import device_pb2_grpc



# 模拟设备数据

devices = {

    "123": {"name": "Device 123", "status": "online", "last_seen": "2023-01-01T00:00:00Z"},

    "456": {"name": "Device 456", "status": "offline", "last_seen": "2023-01-02T12:00:00Z"}

}



class DeviceManagerServicer(device_pb2_grpc.DeviceManagerServicer):

    def GetDevice(self, request, context):

        if request.device_id not in devices:

            context.set_code(grpc.StatusCode.NOT_FOUND)

            context.set_details("Device not found")

            return device_pb2.DeviceResponse()

        device = devices[request.device_id]

        return device_pb2.DeviceResponse(

            device_id=request.device_id,

            name=device['name'],

            status=device['status'],

            last_seen=device['last_seen']

        )



    def CreateDevice(self, request, context):

        if not request.name:

            context.set_code(grpc.StatusCode.INVALID_ARGUMENT)

            context.set_details("Invalid request")

            return device_pb2.DeviceResponse()

        device_id = str(len(devices) + 1)

        devices[device_id] = {

            "name": request.name,

            "status": request.status or "online",

            "last_seen": request.last_seen or datetime.datetime.utcnow().isoformat() + "Z"

        }

        return device_pb2.DeviceResponse(

            device_id=device_id,

            name=devices[device_id]['name'],

            status=devices[device_id]['status'],

            last_seen=devices[device_id]['last_seen'],

            message="Device created"

        )



    def UpdateDevice(self, request, context):

        if request.device_id not in devices:

            context.set_code(grpc.StatusCode.NOT_FOUND)

            context.set_details("Device not found")

            return device_pb2.DeviceResponse()

        if not request.name:

            context.set_code(grpc.StatusCode.INVALID_ARGUMENT)

            context.set_details("Invalid request")

            return device_pb2.DeviceResponse()

        device = devices[request.device_id]

        device['name'] = request.name

        device['status'] = request.status or device['status']

        device['last_seen'] = request.last_seen or device['last_seen']

        return device_pb2.DeviceResponse(

            device_id=request.device_id,

            name=device['name'],

            status=device['status'],

            last_seen=device['last_seen'],

            message="Device updated"

        )



    def DeleteDevice(self, request, context):

        if request.device_id in devices:

            del devices[request.device_id]

            return device_pb2.DeviceResponse(message="Device deleted")

        else:

            context.set_code(grpc.StatusCode.NOT_FOUND)

            context.set_details("Device not found")

            return device_pb2.DeviceResponse()



    def ListDevices(self, request, context):

        device_responses = []

        for device_id, device in devices.items():

            device_responses.append(device_pb2.DeviceResponse(

                device_id=device_id,

                name=device['name'],

                status=device['status'],

                last_seen=device['last_seen']

            ))

        return device_pb2.ListDevicesResponse(devices=device_responses)



def serve():

    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

    device_pb2_grpc.add_DeviceManagerServicer_to_server(DeviceManagerServicer(), server)

    server.add_insecure_port('[::]:50051')

    server.start()

    print("Server started on port 50051")

    try:

        while True:

            time.sleep(86400)

    except KeyboardInterrupt:

        server.stop(0)



if __name__ == '__main__':

    serve()

客户端实现

# client.py

import grpc

import device_pb2

import device_pb2_grpc



def get_device(stub, device_id):

    response = stub.GetDevice(device_pb2.DeviceRequest(device_id=device_id))

    print(f"Device: {response.device_id}, Name: {response.name}, Status: {response.status}, Last Seen: {response.last_seen}")



def create_device(stub, name, status=None, last_seen=None):

    response = stub.CreateDevice(device_pb2.DeviceRequest(name=name, status=status, last_seen=last_seen))

    print(f"Device created: {response.device_id}, Name: {response.name}, Status: {response.status}, Last Seen: {response.last_seen}")



def update_device(stub, device_id, name, status=None, last_seen=None):

    response = stub.UpdateDevice(device_pb2.DeviceRequest(device_id=device_id, name=name, status=status, last_seen=last_seen))

    print(f"Device updated: {response.device_id}, Name: {response.name}, Status: {response.status}, Last Seen: {response.last_seen}")



def delete_device(stub, device_id):

    response = stub.DeleteDevice(device_pb2.DeviceRequest(device_id=device_id))

    print(f"Device deleted: {response.device_id}")



def list_devices(stub):

    response = stub.ListDevices(device_pb2.ListDevicesRequest())

    for device in response.devices:

        print(f"Device: {device.device_id}, Name: {device.name}, Status: {device.status}, Last Seen: {device.last_seen}")



def run():

    channel = grpc.insecure_channel('localhost:50051')

    stub = device_pb2_grpc.DeviceManagerStub(channel)



    print("1. Get device")

    print("2. Create device")

    print("3. Update device")

    print("4. Delete device")

    print("5. List devices")



    choice = input("Choose an option: ")



    if choice == "1":

        device_id = input("Enter device ID: ")

        get_device(stub, device_id)

    elif choice == "2":

        name = input("Enter device name: ")

        status = input("Enter device status (optional): ")

        last_seen = input("Enter last seen time (optional): ")

        create_device(stub, name, status, last_seen)

    elif choice == "3":

        device_id = input("Enter device ID: ")

        name = input("Enter device name: ")

        status = input("Enter device status (optional): ")

        last_seen = input("Enter last seen time (optional): ")

        update_device(stub, device_id, name, status, last_seen)

    elif choice == "4":

        device_id = input("Enter device ID: ")

        delete_device(stub, device_id)

    elif choice == "5":

        list_devices(stub)

    else:

        print("Invalid choice")



if __name__ == '__main__':

    run()

运行和测试

首先运行 gRPC 服务器:


python server.py

然后运行 gRPC 客户端:


python client.py

根据提示选择操作,例如:

  • 获取指定设备

Choose an option: 1

Enter device ID: 123

Device: 123, Name: Device 123, Status: online, Last Seen: 2023-01-01T00:00:00Z

  • 创建设备

Choose an option: 2

Enter device name: New Device

Enter device status (optional): online

Enter last seen time (optional): 2023-01-03T00:00:00Z

Device created: 3, Name: New Device, Status: online, Last Seen: 2023-01-03T00:00:00Z

  • 更新设备

Choose an option: 3

Enter device ID: 123

Enter device name: Updated Device 123

Enter device status (optional): offline

Enter last seen time (optional): 2023-01-04T00:00:00Z

Device updated: 123, Name: Updated Device 123, Status: offline, Last Seen: 2023-01-04T00:00:00Z

  • 删除设备

Choose an option: 4

Enter device ID: 123

Device deleted: 123

  • 获取所有设备

Choose an option: 5

Device: 456, Name: Device 456, Status: offline, Last Seen: 2023-01-02T12:00:00Z

Device: 3, Name: New Device, Status: online, Last Seen: 2023-01-03T00:00:00Z

总结

  • RESTful API:适用于简单的 Web 应用和移动应用,易于理解和调试,但性能和扩展性相对较低。

  • gRPC:适用于高性能、低延迟和复杂通信模式的场景,如微服务架构和实时数据流,但学习曲线较高,需要生成代码。

选择合适的 API 技术取决于具体的应用需求。在需要高性能和复杂通信模式的情况下,gRPC 是一个更好的选择。而在简单的 Web 应用和移动应用中,RESTful API 仍然是一种非常流行和实用的解决方案。

标签:status,name,gRPC,IoT,devices,device,二次开发,seen,id
From: https://blog.csdn.net/chenlz2007/article/details/143027302

相关文章

  • Android 音频采集/音频播放【AudioTrack、AudioRecord】
    项目中遇到需求,采集音频上传至公司编译的sdk内,播放sdk传递过来的音频,所以自行实现了一个采集音频与播放音频的方法代码:importandroid.Manifestimportandroid.app.Activityimportandroid.content.pm.PackageManagerimportandroid.media.AudioFormatimportandroid.me......
  • CAD软件:GstarCAD二次开发
    GstarCAD二次开发入门1.1二次开发概述GstarCAD是一款功能强大的CAD软件,广泛应用于建筑设计、机械制造、电子工程等领域。二次开发是指在现有的GstarCAD软件基础上,通过编程技术扩展其功能,满足特定的业务需求。二次开发可以大大提升工作效率,帮助用户解决复杂的设计问题。......
  • 通信工程学习:什么是AIOT智能物联网
    AIOT:智能物联网        AIOT智能物联网,即ArtificialIntelligenceofThings(人工智能物联网),是人工智能(AI)与物联网(IoT)技术的深度融合。这一技术通过物联网产生、收集来自不同维度的海量数据,并存储在云端或边缘端,随后利用大数据分析以及更高层次的人工智能技术,实现万物......
  • 一款Java CMS 网站管理系统,基于RuoYi-fast二次开发,网站后台采用SpringBoot + MyBati
    一款JavaCMS网站管理系统基于RuoYi-fast二次开发,网站后台采用SpringBoot+MyBatis文章目录前言一、开源地址二、环境要求三、功能亮点3.1扩展功能3.2内置功能四、安装方法4.1、拉取源码4.2、修改数据库链接配置4.3、创建数据库并导入数据4.4、配置资源上传......
  • 【gRPC】2—gRPC与PB&桩代码生成与扩展
    gRPC与PB&桩代码生成与扩展⭐⭐⭐⭐⭐⭐Github主页......
  • PatriotCTF2024 Web Impersonate
    源码:#!/usr/bin/envpython3fromflaskimportFlask,request,render_template,jsonify,abort,redirect,sessionimportuuidimportosfromdatetimeimportdatetime,timedeltaimporthashlibapp=Flask(__name__)server_start_time=datetime.now()server_s......
  • 轻松上云怎么操作?IoT_CLOUD之中移OneNET
    ​ 最近来了很多新朋友,也经常被问:可以多讲些云平台的操作吗?当然可以!文末留言你想要了解的云平台,优先安排~接下来,本文将以Air780E+LuatOS作为示例,教你使用合宙IoT_CLOUD连接中移OneNET物联网云平台。 一、IoT_CLOUD简 1.1IoT_CLOUD特色简介IoT_CLOUD——是合宙专门为了......
  • GUI图形界面 无代码开发 原理 - 属性标识链 | uiotos致敬amis、nodered、appsmith、co
    低代码饱受争议。也有例外:后端NodeRed,前端Amis。整体还是诟病为主:简单业务可以,复杂的是扯淡,不论前后端。这是一贯的认知。在GUI方面,UIOTOS发明的嵌套技术,为复杂前端的无代码开发,开辟了一条新的思路。往期文章:可视化拖拉拽?过时了!组态零代码,不能做复杂前端?嵌套原理一复杂交互......
  • 组态也能开发WEB前端 | uiotos致敬amis、nodered、appsmith、codewave、goview、datar
    WEB组态开发SCADA、HMI画面、大屏可视化,还比较常见。比如下面: UIOTOS组态示例那么常规WEB前端功能,组态能否一并做了呢?比如下面这种: UIOTOS前端示例答案是可以的!UIOTOS支持页面无限嵌套,能实现原型即应用。现在就以一个具体小示例介绍如何实现的。效果如下所示,初......
  • 前端无代码-表单页面的查看和编辑| uiotos致敬amis、appsmith、codewave、goview、dat
    上位机或管理系统,增删改查属于常规操作。其中以点击以查看和编辑,弹出表单页面,最为常见。 UIOTOS支持页面嵌套、属性继承(包括只读属性)。通过配置和连线,也能对表单页面区分查看和编辑,但有些繁琐。可以利用容器组件的表单只读属性,勾选后,连线传入表单数据,将只读显示。 文档地......