(二)、canal学习笔记之编写canal c#客户端

安装

1、新建.net core 6.0 控制台项目

在这里插入图片描述

2、引入CanalSharp包

在这里插入图片描述

3、开始编写代码

  1. 初始化日志,引入包Microsoft.Extensions.Logging.Console
var loggerFactory = LoggerFactory.Create(builder =>
{
    builder
        .AddFilter("Microsoft", LogLevel.Debug)
        .AddFilter("System", LogLevel.Information)
        .AddConsole();
});
var logger = loggerFactory.CreateLogger<SimpleCanalConnection>();
  1. 创建连接
var conn=new SimpleCanalConnection(new SimpleCanalOptions("127.0.0.1",11111,"1234"),logger);
//连接到 Canal Server
await conn.ConnectAsync();
//订阅
await conn.SubscribeAsync();
  1. 获取数据
var msg = await conn.GetAsync(1024);
  1. 解析数据
  • Entry
    conn.GetAsync()返回的是一个 Entry 集合,Entry 对应 binlog 记录,它可能是事务标记也有可能是行数据变化,通过 Entry.EntryType 来区分,一般事务的标记在业务消费处理时不需要处理。
    示例:
var entries = await conn.GetAsync(1024);
foreach (var entry in entries)
{
    //不处理事务标记
    if (entry.EntryType == EntryType.Transactionbegin || entry.EntryType == EntryType.Transactionend)
    {
        continue;
    }
}

Entry.Header 包含了一些binlog以及数据库信息

属性说明
Entry.Header.LogfileNamebinlog 文件名
Entry.Header.LogfileOffsetbinlog 偏移
Entry.Header.SchemaNamemysql schema 名称
Entry.Header.TableName表名
  • RowChange
    一般在业务处理中,都会需要行数据的变更,将 Entry 转换为 RowChange对象
    示例:
RowChange rowChange = null;
try
{
    rowChange = RowChange.Parser.ParseFrom(entry.StoreValue);
}
catch (Exception e)
{
    _logger.LogError(e);
}

通过 RowChange.EventType 来Row是什么变化,Update、Delete和 Insert 对应 sql 中的 update、delete 和 insert 语句
通过 RowChange.RowDatas 属性,来访问 RowChange 对象中包含的行变化数据集合。
示例,遍历 RowChange 中的行数据:

foreach (var rowData in rowChange.RowDatas)
{
    //删除的数据
    if (eventType == EventType.Delete)
    {
        PrintColumn(rowData.BeforeColumns.ToList());
    }
    //插入的数据
    else if (eventType == EventType.Insert)
    {
        PrintColumn(rowData.AfterColumns.ToList());
    }
    //更新的数据
    else
    {
        _logger.LogInformation("-------> before");
        PrintColumn(rowData.BeforeColumns.ToList());
        _logger.LogInformation("-------> after");
        PrintColumn(rowData.AfterColumns.ToList());
    }
}

private static void PrintColumn(List<Column> columns)
{
    foreach (var column in columns)
    {
        Console.WriteLine($"{column.Name}{column.Value}  update=  {column.Updated}");
    }
}
  • Column
    Column 如其名,代表数据库中表的每一列的信息。
属性名说明
Column.Name列名
Column.Value列的值
Column.Updated列是否被更新

如执行 sql update user set Name='Allen',那么获取到的数据变更则有

Column.Name = 'Name';
Column.Value = 'Allen';
Column.Value = True
  • 应答机制
    应答机制可以保证消费数据的准确性,Canal 服务端会记录 Client 消费的进度,需要客户端发送 ACK 消息,服务端才会更新进度。类似于在消息队列中的 ACK 机制,如 RabbitMQ。
  1. 自动应答
await conn.GetAsync(1024);//获取数据并自动应答
  1. 手动应答
var msg = await conn.GetWithoutAckAsync(1024);//获取数据
await conn.AckAsync(msg.Id);//手动应答
await conn.RollbackAsync(msg.Id);//回滚

4、启动客户端

新建数据库test,和添加表t1,并添加一条记录,就会收到canal服务器传过来的数据
在这里插入图片描述
客户端完整代码如下:

using CanalSharp.Connections;
using CanalSharp.Protocol;
using Microsoft.Extensions.Logging;
using System;

namespace CanalClientDemo
{
    internal class Program
    {
        static async Task Main(string[] args)
        {
            //1.初始化日志
            var loggerFactory = LoggerFactory.Create(builder =>
            {
                builder
                    .AddFilter("Microsoft", LogLevel.Debug)
                    .AddFilter("System", LogLevel.Information)
                    .AddConsole();
            });
            var logger = loggerFactory.CreateLogger<SimpleCanalConnection>();
            //2.创建连接
            var conn = new SimpleCanalConnection(new SimpleCanalOptions("127.0.0.1", 11111, "1234"), logger);
            //连接到 Canal Server
            await conn.ConnectAsync();
            //订阅
            await conn.SubscribeAsync();
            //3.获取数据
            while (true)
            {
                var msg = await conn.GetAsync(1024);
                if (msg.Entries.Count <= 0)
                {
                    Thread.Sleep(1000);
                    continue;
                }
                foreach (var entry in msg.Entries)
                {
                    //不处理事务标记
                    if (entry.EntryType == EntryType.Transactionbegin || entry.EntryType == EntryType.Transactionend)
                    {
                        continue;
                    }
                    RowChange rowChange = RowChange.Parser.ParseFrom(entry.StoreValue);
                    foreach (var rowData in rowChange.RowDatas)
                    {

                    }
                }
            }

        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值