日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

uservice

更正文檔

概述

uService(微服務)是一種支持RPC請求/應用的交互,并支持狀態消息發布的一種服務機制,客戶端可以通過發送請求消息并待回復的方式調用uService(微服務)提供的服務,也可以通過訂閱服務的事件,來處理服務的事件狀態。

serviceTask(服務任務)是利用操作系統的多任務系統,實現消息的分發機制,一個 serviceTask中創建一個OS 的Task。一個serviceTask 下可以注冊多個微服務,同一個服務任務下的所有微服務的消息采用先進先處理的順序執行。

接口定義

RPC

typedef struct _rpc_t {
    uservice_t   *srv;
    uint32_t      cmd_id;
    rpc_buffer_t *data;
} rpc_t;
  • cmd_id: RPC 序號

  • data: 存RPC相關參數的buffer

RPC 初始化

int  rpc_init(rpc_t *rpc, int cmd_id, int timeout_ms);

初始化 RPC,設置 RPC 的命令號(cmd_id),命令調用的超時時間(timeout_ms),單位毫秒

  • 參數:

    • rpc: rpc

    • cmd_id: RPC 的命令號

    • timeout_ms: 命令調用等待超時時間,0時為異步調用,調用者立即返回,等于 AOS_WAIT_FOREVER為同步調用,等到服務端命令執行完,當 timeout_ms 大于0時,為超時調用,調用者指定的時間內等待服務端返回,如果服務器未返回,則超時退出

  • 返回值:

    • 0: 成功

    • -ENOMEM: 內存不足

    • -EINVAL: 無效參數

RPC 寫參數復位

void rpc_put_reset(rpc_t *rpc);

清空 rpc 內部的參數。rpc 參數是調用者向服務端傳遞輸入參數,也是服務端向調用者返回參數。編寫服務端程序時,在處理完成 rpc 的參數,需要向調用者返回值時,通過調用該函數,清空參數區,然后通過 rpc_put_xxx 函數向 rpc 寫入返回值。

RPC 寫入參數

int rpc_put_int(rpc_t *rpc, int v);
int rpc_put_uint8(rpc_t *rpc, uint8_t v);
int rpc_put_double(rpc_t *rpc, double v);
int rpc_put_point(rpc_t *rpc, const void *v);
int rpc_put_buffer(rpc_t *rpc, const void *data, size_t size);
int rpc_put_string(rpc_t *rpc, char *str);

向 rpc 參數區寫入參數, rpc 的參數可以寫入多個參數,根據寫入的順序存放。參數區可以寫入 int、uint8_t、double、point、string、array 類型的數據。

  • 返回值:

    • 0: 成功

    • -ENOMEM: 內存不足

RPC 參數讀取復位

void    rpc_get_reset(rpc_t *rpc);

RPC 參數區讀取位復。rpc 參數區的參數通管 rpc_get_xxx 一組函數讀取,每調用一次讀取函數則取出一個參數,序號遞增,如果需要從頭重新讀取參數,則通過 rpc_get_reset 函數,將參數序號移到起始位置。

RPC 參數讀取

int     rpc_get_int(rpc_t *rpc);
uint8_t rpc_get_uint8(rpc_t *rpc);
double  rpc_get_double(rpc_t *rpc);
char   *rpc_get_string(rpc_t *rpc);
void   *rpc_get_point(rpc_t *rpc);
void   *rpc_get_buffer(rpc_t *rpc, int *count);

從參數區讀取參數,在參數讀取時,要調用與寫入時的參數順序一致,參數區的參數是順序讀取,每調用一次 rpc_get_xxx 函數,則依次讀出一個參數。參數讀取類型不一致時,會導致異常。返回參數值。

RPC 應答

void rpc_reply(rpc_t *rpc);

該函數在編寫服務端時調用,當服務端處理完一條 rpc 時,必須調用該函數完成 rpc 的任務處理。

RPC 回收

void rpc_deinit(rpc_t *rpc);

該函數在調用端執行,當調用者使用 uservice_call 函數調用 rpc時,在處理完 rpc 返回值后,需要調用 rpc_deinit 函數回收 rpc 資源。

創建微服務

uservice_t *uservice_new(const char *name, process_t process_rpc, void *context);

根據指定的微服務名稱,上下文、最大命令ID,創建微服務,創建成功返回 uservice_t 指針,失敗返回NULL

  • 參數:

    • name: 服務名字

    • process_rpc: 服務遠程調用處理函數

    • context: 服務自定義上下文,用戶在編寫微服務處理函數時,可使用該上下文

  • 返回值:創建成功返回 uservice_t 指針,失敗返回NULL

釋放微服務

void uservice_destroy(uservice_t *srv);

釋放微服務 srv 所占用所有資源,釋放srv 之前,需要確定眾uservice_task 中移出 uService

微服務 rpc 處理函數

typedef int (*process_t)(void *context, rpc_t *rpc);

微服務的遠程調用(RPC)的主處理函數,在微服務開發時,盡可能減少 process_rpc 的處理時間。

  • context: 創建微服務時傳入的 context

  • rpc:遠程序調用對象

同步調用微服務命令

int  uservice_call_sync(uservice_t *srv, int cmd, void *param, void *resp, size_t resp_size);

向微服務發送一條同步執行命令

  • 參數:

    • srv: 微服務

    • cmd:指定需要執行的命令號

    • param: 命令的參數

    • resp:命令的返回值

    • resp_size: 命令返回值空間大小

  • 返回值:調用成功,返回0,否則返回 -1

異步調用微服務命令

int  uservice_call_async(uservice_t *srv, int cmd, void *param, size_t param_size);

向微服務發送一條異步執行命令

  • 參數:

    • srv: 微服務

    • cmd:指定需要執行的命令號

    • param: 命令的參數

    • param_size: 命令參數空間大小

  • 返回值:調用成功,返回0,否則返回 -1

自定義調用微服務命令

int  uservice_call(uservice_t *srv, rpc_t *rpc);

使用自定義 rpc 實現微服務的命令調用,該命令可以通過 rpc_t 實現同步、異步、超時調用,也可以用 rpc_put_xxx 函數,向 rpc 中傳入多個參數。服務器也可以通過 rpc 返回多個數據,可以實現復雜參數傳輸調用。

  • 參數:

    • srv: 微服務

    • rpc: 調用的 RPC 指令

  • 返回值:調用成功,返回0,否則返回 -1

微服務鎖操作

void uservice_lock(uservice_t *srv);
void uservice_unlock(uservice_t *srv);

微服務事件訂閱

void uservice_subscribe(uservice_t *srv, uint32_t event_id);

該函數用于微服務中,調用該函數訂閱事件,并將事件發送到微服務的 RPC 任務隊列中,RPC 的 cmd_id 等于 event_id,通過 rpc_get_pointer 可以獲取事件的 data 參數。

struct demo_service {
    uservice_t *srv;
} demo_svr;

static void process_rpc(void *context, rpc_t *rpc)
{
    switch (rpc->cmd_id) {
        case EVENT_NETMGR_GOT_IP: {
            /* EVENT_NETMGR_GOT_IP 事件處理 */
            void *data = rpc_get_pointer(rpc);
            if (data != NULL) {
                // TODO:
            }
            ...
            break;
        }
        ...
    }

    rpc_reply(rpc);
}

void demo_service_init()
{
     /* 創建一個微服務 */
    demo_svr.srv = uservice_new("demo", process_rpc, NULL);
    /* 訂閱微服務事件 “EVENT_NETMGR_GOT_IP”*/
    uservice_subscribe(demo_svr.srv, EVENT_NETMGR_GOT_IP);
}

事件

支持全局事件,已定義的事件在 include/uservice/eventid.h 文件中。事件有兩種,一種是普通事件,事件的 event_id 由用戶定義,由于事件的ID是全局唯一,用戶自定義事件時,不能與系統事件沖突。一種是設備(網絡)句柄數據可讀事件,當設備有數據可讀時,會觸發 fd 事件。

事件訂閱

void event_subscribe(uint32_t event_id, event_callback_t cb, void *context);
void event_subscribe_fd(uint32_t fd, event_callback_t cb, void *context);

typedef void (*event_callback_t)(uint32_t event_id, const void *data, void *context);

event_subscribe 訂閱普通事件,event_subscribe_fd 訂閱設備(網絡)句柄數據可讀事件

  • 參數:

    • event_id: 事件號, event_subscribe_fd 函數,fd 為設備/網絡句柄。

    • cb: 事件處理函數,該參數不能為 NULL,否則會觸發異常

    • context: 用戶數據,該數據會傳入到 cb 的 context 參數中

  • 返回值:無

事件訂閱取消

void event_unsubscribe(uint32_t event_id, event_callback_t cb, void *context);
void event_unsubscribe_fd(uint32_t fd, event_callback_t cb, void *context);

取消事件訂閱,取消事件訂閱時,要求傳入的參數與訂閱時的參數一致方可取消

  • 參數:

    • event_id: 事件號, event_subscribe_fd 函數,fd 為設備/網絡句柄。

    • cb: 事件處理函數,該參數不能為 NULL,否則會觸發異常

    • context: 用戶數據,該數據會傳入到 cb 的 context 參數中

  • 返回值:無

事件發布

void event_publish(uint32_t event_id, void *data);
void event_publish_fd(uint32_t fd, void *data, int sync);

發布事件

  • 參數:

    • event_id: 事件號, event_publish_fd 函數,fd 為設備/網絡句柄。

    • data: 事件附帶數據,該數據會傳到訂閱者的回調函數參數 data中,由于事件是異步處理,使用者要小心使用 data 的作用域,訂閱者能正常訪問該數據

    • sync: 同步標志,1:同步 0:異步

  • 返回值:無

創建微服務任務

utask_t    *utask_new(const char *name, size_t stack_size, int queue_length, int prio);
  • 參數:

    • name: utask名

    • stack_size:棧大小

    • queue_length:隊列個數

    • prio:優先級

  • 返回值:非NULL:成功 NULL:失敗

釋放微服務任務

void utask_destroy(utask_t *task);

向微服務任務中添加(刪除)微服務

void utask_add(utask_t *task, uservice_t *srv);
void utask_remove(utask_t *task, uservice_t *srv);

等待微服務任務退出并收回占用資源

void utask_join(utask_t *task);

示例代碼

服務接口及事件定義

#ifndef DEMO_SERVICE_H
#define DEMO_SERVICE_H

#define EVENT_A 0x1000
#define EVENT_B 0x1001

服務實現

#include <uservice/uservice.h>

struct demo_uservice {
    uservice_t *srv;
    int a, b, c;
    rpc_t *current_cmd;
    rpc_t *current_oob;
};

/* cmd 列表 */
enum DEMO_CMD {
    CMD_1 = 0,
    CMD_2 = 1,
    CMD_RECV,

    CMD_DATA = 10,
    CMD_MAX
};
/* 事件ID */
#define EVENT_A 0x1000
#define EVENT_B 0x1001
#define EVENT_C 0x1002

struct cmd_param {
    int a, b, c;
};

/* 微服務處理函數*/
static int process_rpc(void *context, rpc_t *rpc)
{
    struct demo_uservice *d = (struct demo_uservice *)context;

    if (rpc->cmd_id < CMD_DATA) {
        d->current_cmd = rpc;
    }

    switch (rpc->cmd_id) {
        case CMD_RECV:
            // d->current_cmd = rpc;
            break;

        case CMD_1: {
            /* 加法cmd 處理 */
            struct cmd_param *p = (struct cmd_param *)rpc_get_point(rpc);

            d->c =  p->a + p->b;

            /* 發布 EVENT_A 事件 */
            event_publish(EVENT_A, (void *)d->c);
            break;
        }

        case CMD_DATA:
            if (d->current_cmd != NULL) {
                rpc_reply(d->current_cmd);
                d->current_cmd = NULL;
                event_publish(EVENT_A, (void *)d->c);
            }
   /* rpc應答 */
            rpc_reply(rpc);
            break;

        default:
            /* rpc應答 */
            rpc_reply(rpc);
            break;
    }

    return 0;
}

static struct demo_uservice demo;
void demo_service_init()
{
    static utask_t *srv;
 /* 創建微服務 */
    srv = utask_new("demo_srv", 2 * 1024, QUEUE_MSG_COUNT, AOS_DEFAULT_APP_PRI);
 /* 創建utask */
    demo.srv = uservice_new("demo", process_rpc, &demo);

    /* 將微服務加入到utask中 */
    utask_add(srv, demo.srv);
}

void demo_add(int a, int b)
{
    struct cmd_param cmd;
    cmd.a = a;
    cmd.b = b;
    int c;

    /* 微服務同步調用 CMD_1 */
    uservice_call_sync(demo.srv, CMD_1, &cmd, &c, sizeof(int));
}

服務調用

int demo_subscribe(uint16_t event_id, event_callback_t cb, void *context)
{
    return uservice_subscribe(demo.srv, event_id, cb, context);
}

static void event_a_callback(uint16_t event_id, const void *data, void *context)
{
    printf("%d\n", (int)data);
}

void demo_test()
{
    demo_service_init();
    demo_subscribe(EVENT_A, event_a_callback, NULL);
    demo_add(1, 4);
}