db_set_active() 访问多个数据库

本文介绍了如何在PHP项目中配置并实现多个数据库的访问。通过示例代码详细展示了在settings.php文件中设置不同数据库连接的方法,并提供了如何在代码中进行数据库切换的具体步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

若想访问多个数据库,首先需要在settings.php中,配置好多个数据库:

$databases = array (
  'default' => 
  array (
    'default' => 
    array (
      'database' => 'tianjinyizhuan',
      'username' => 'tianjinyizhuan',
      'password' => 'tianjinyizhuan',
      'host' => 'localhost',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ),
  ),
  'commons' => 
  array (
    'default' => 
    array (
      'database' => 'commons',
      'username' => 'commons',
      'password' => 'commons',
      'host' => 'localhost',
      'port' => '',
      'driver' => 'mysql',
      'prefix' => '',
    ),
  ),
);

然后,在代码中访问别的数据库:

db_set_active('commons'); // 切换到commons定义的数据库
// 操作数据库commons
db_set_active(); //转到默认数据库
<think>我们正在使用BlueZ的GATT数据库(GATT DB)API来实现CCC(ClientCharacteristicConfiguration)描述符的注册和通知功能。根据用户的问题,重点是注册CCC并实现通知功能。以下步骤将详细说明:1.**创建GATT服务**:首先需要创建一个GATT服务,并在该服务下添加特征值(Characteristic)和描述符(Descriptor)。2.**添加特征值并启用通知属性**:在创建特征值时,需要指定其属性包括`BT_GATT_CHRC_PROP_NOTIFY`,这样BlueZ会自动为该特征值添加CCC描述符。3.**注册CCC描述符的回调函数**:当客户端写入CCC描述符(启用或禁用通知)时,我们需要一个回调函数来处理这个事件。这个回调函数将在CCC值改变时被调用。4.**在回调函数中处理订阅状态**:在CCC回调函数中,我们可以获取客户端设置的CCC值(0x0001表示启用通知,0x0002表示启用指示,0x0000表示禁用)。根据这个值,我们可以启动或停止向该客户端发送通知。5.**发送通知**:当特征值发生变化时,调用`gatt_db_attribute_notify`函数向所有已订阅的客户端发送通知。 下面我们详细说明每一步: ###1.创建GATT服务首先,我们需要创建一个GATT服务。这通常是在初始化GATT数据库时完成的。```cstaticstruct gatt_db*db; db= gatt_db_new();structgatt_db_attribute*service= gatt_db_add_service(db,&primary_uuid, true,10);```这里,`primary_uuid`是服务的UUID,`true`表示这是一个主服务,`10`表示该服务需要10个属性句柄(根据实际需要调整)。 ###2.添加特征值并启用通知属性接下来,我们在服务中添加特征值,并设置其属性为`BT_GATT_CHRC_PROP_NOTIFY`(同时可能还有其他属性,如`BT_GATT_CHRC_PROP_READ`)。 ```cbt_uuid_tchar_uuid;bt_uuid16_create(&char_uuid,0x2A37);//例如,心率测量特征struct gatt_db_attribute *char_attr =gatt_db_service_add_characteristic(service,&char_uuid,BT_ATT_PERM_READ |BT_ATT_PERM_WRITE, //权限:这里CCC描述符需要写入权限,所以特征值可能需要WRITE权限?实际上CCC描述符的权限是单独设置的,但通常特征值本身不需要WRITE权限来支持通知。BT_GATT_CHRC_PROP_READ| BT_GATT_CHRC_PROP_NOTIFY, //属性char_read_callback,//读取回调,当客户端读取特征值时调用NULL,//写入回调,这里不需要,因为特征值本身不可写ccc_write_callback//CCC描述符改变时的回调函数);``` 注意:`gatt_db_service_add_characteristic`函数的最后一个参数就是CCC描述符改变时的回调函数。BlueZ在内部会自动创建CCC描述符,并在这个回调函数中通知我们CCC值的变化。###3.实现CCC回调函数我们需要实现`ccc_write_callback`函数,该函数在客户端写入CCC描述符时被调用。```cstaticvoid ccc_write_callback(struct gatt_db_attribute *attrib,unsigned intccc_value,void *user_data) {//ccc_value是客户端写入的值//0x0001表示启用通知,0x0002表示启用指示,0x0000表示禁用if(ccc_value &0x0001) {//客户端启用了通知//可以在这里记录客户端需要通知,或者启动一个定时器来定期发送通知//例如:将客户端加入通知列表}else if(ccc_value ==0) {//客户端禁用了通知//从通知列表中移除该客户端}} ```###4.发送通知当特征值发生变化时,我们需要向所有启用了通知的客户端发送通知。但是,BlueZ的GATT数据库API并没有直接提供获取所有已订阅客户端的功能。因此,我们需要自己维护一个列表来记录哪些客户端订阅了通知,或者使用BlueZ提供的其他机制(如通过连接对象)。然而,实际上,我们可以使用`gatt_db_attribute_notify`函数,它会自动处理已订阅的客户端。也就是说,BlueZ内部会跟踪每个连接的CCC值,所以当我们调用`gatt_db_attribute_notify`时,它会检查哪些客户端订阅了该特征值的通知,并只向这些客户端发送。```c//当特征值需要更新时,调用此函数void notify_characteristic(structgatt_db_attribute*attr, constuint8_t *value,size_tlen){//使用gatt_db_attribute_notify发送通知gatt_db_attribute_notify(attr,NULL,value,len,NULL);} ```注意:`gatt_db_attribute_notify`的第二个参数是连接对象(`structbt_conn*`),如果传入NULL,则会向所有订阅了该特征值通知的客户端发送。###5.注册服务并激活最后,不要忘记注册服务并激活数据库。 ```cgatt_db_service_set_active(service,true);``` ###总结步骤1.创建GATT数据库。 2.在数据库中创建服务。3.在服务中添加特征值,并设置属性包含`BT_GATT_CHRC_PROP_NOTIFY`,同时指定CCC描述符的回调函数。 4.在CCC回调函数中处理客户端的订阅和取消订阅。 5.当特征值变化时,调用`gatt_db_attribute_notify`发送通知。###注意事项-确保在特征值属性中设置了`BT_GATT_CHRC_PROP_NOTIFY`,这样BlueZ才会自动添加CCC描述符。- CCC描述符的UUID固定为0x2902,权限通常为`BT_ATT_PERM_READ |BT_ATT_PERM_WRITE`(由BlueZ内部设置)。-在发送通知时,数据长度不能超过当前连接的MTU大小。###相关问题1.如何在BlueZ中实现GATT指示(Indication)功能?2.如何管理多个客户端订阅同一个特征值的通知?3.当客户端断开连接时,BlueZ会自动处理CCC订阅状态吗?4.如何通过D-Bus接口控制GATT通知? [^1]:引用自BlueZ的GATT实现概述[^2]:引用自BlueZ的订阅API说明</think>### BlueZ GATT Server CCC注册与通知实现指南 在BlueZ中实现GATT特征值通知功能的核心是正确配置CCC(Client Characteristic Configuration)描述符。以下是详细步骤: #### 1. **创建GATT服务与特征值** ```c // 创建GATT数据库 struct gatt_db *db = gatt_db_new(); // 添加主服务 (示例UUID: 0x180D) bt_uuid_t service_uuid; bt_uuid16_create(&service_uuid, 0x180D); struct gatt_db_attribute *service = gatt_db_add_service(db, &service_uuid, true, 10); // 添加特征值并启用NOTIFY属性 bt_uuid_t char_uuid; bt_uuid16_create(&char_uuid, 0x2A37); // 心率测量特征 struct gatt_db_attribute *char_attr = gatt_db_service_add_characteristic( service, &char_uuid, BT_ATT_PERM_READ, // 读取权限 BT_GATT_CHRC_PROP_READ | BT_GATT_CHRC_PROP_NOTIFY, // 关键:启用NOTIFY NULL, // 读取回调 NULL, // 写入回调 ccc_write_callback // CCC描述符回调 ); ``` [^1] #### 2. **实现CCC描述符回调** 当客户端写入CCC值时触发此回调: ```c static void ccc_write_callback(struct gatt_db_attribute *attrib, unsigned int ccc_value, void *user_data) { printf("CCC值更新: 0x%04X\n", ccc_value); if (ccc_value & 0x0001) { // 通知启用标志 enable_notifications(); } else if (ccc_value == 0) { disable_notifications(); } } ``` - `0x0001` = 启用通知 - `0x0002` = 启用指示 - `0x0000` = 禁用通知[^2] #### 3. **发送通知** 当特征值变化时调用: ```c void send_heart_rate_notification(uint8_t hr_value) { uint8_t data[2] = {0x00, hr_value}; // 格式标志+心率值 // 向所有订阅客户端发送通知 gatt_db_attribute_notify(char_attr, NULL, data, sizeof(data), NULL); } ``` - 第一个参数:特征值属性句柄 - 第二个参数:目标连接(NULL表示所有订阅客户端) - 通知自动通过ATT协议发送[^1] #### 4. **订阅管理(高级)** 管理多个客户端订阅: ```c // 获取当前CCC配置 unsigned int ccc_value = gatt_db_attribute_get_ccc(char_attr); // 检查特定连接是否订阅 struct bt_conn *conn = ...; // 获取连接对象 if (gatt_db_attribute_ccc_get(conn, char_attr) & 0x0001) { // 该连接已启用通知 } ``` #### 5. **D-Bus控制接口** 通过D-Bus管理通知: ```python # Python示例:启用通知 import dbus bus = dbus.SystemBus() char_obj = bus.get_object("org.bluez", "/org/bluez/hci0/dev_00_11_22_33_44_55/service000a/char000c") char_iface = dbus.Interface(char_obj, "org.bluez.GattCharacteristic1") char_iface.StartNotify() ``` ### 关键注意事项 1. **CCC自动创建**:当特征值包含`NOTIFY`或`INDICATE`属性时,BlueZ会自动创建CCC描述符(UUID 0x2902)[^1] 2. **权限设置**:CCC描述符默认具有读写权限(`BT_ATT_PERM_READ | BT_ATT_PERM_WRITE`) 3. **连接感知**:通知仅发送给已订阅且处于连接状态的客户端 4. **MTU限制**:通知数据长度不得超过当前连接的ATT_MTU大小 > **调试提示**:使用`bluetoothctl`命令查看CCC状态: > ```bash > select <device> > list-attributes > attribute-info <ccc-handle> > ``` ### 完整流程 ```mermaid sequenceDiagram 客户端->>服务端: 写入CCC值(0x0001) 服务端->>服务端: 触发ccc_write_callback 服务端->>服务端: 启动数据监控 服务端->>客户端: gatt_db_attribute_notify() 客户端->>服务端: 断开连接 服务端->>服务端: 自动清理订阅状态 ``` ### 相关问题 1. 通知(Notification)和指示(Indication)在BlueZ实现中有何本质区别?[^2] 2. 当多个客户端同时订阅同一特征值时,BlueZ如何管理通知发送?[^1] 3. 如何通过Wireshark分析BlueZ发出的GATT通知数据包? 4. BLE连接参数(间隔/延迟)如何影响通知性能?[^1] [^1]: 引用自BlueZ GATT实现概述 [^2]: 引用自BlueZ订阅API文档
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值