以下是一个完整的C#示例,展示如何使用UDP接收数据,将数据保存到Redis,并定时同步到SQL Server数据库中。代码分为三个部分:
-
**UDP数据接收**:使用 `System.Net.Sockets.UdpClient` 接收数据。
-
**Redis数据存储**:使用 `StackExchange.Redis` 将数据缓存到Redis。
-
**定时同步到SQL Server**:使用 `System.Threading.Timer` 定时将Redis中的数据同步到SQL Server。
**实现步骤**
- **安装NuGet包**:
-
`StackExchange.Redis`:用于操作Redis。
-
`System.Data.SqlClient`:用于操作SQL Server。
```bash
dotnet add package StackExchange.Redis
dotnet add package System.Data.SqlClient
```
**代码实现**
**1. UDP数据接收与Redis存储**
```csharp
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;
public class UdpReceiver
{
private readonly IDatabase _redis;
public UdpReceiver(string redisConnectionString)
{
var redis = ConnectionMultiplexer.Connect(redisConnectionString);
_redis = redis.GetDatabase();
}
public async Task StartAsync(int port)
{
using (var udpClient = new UdpClient(port))
{
Console.WriteLine($"UDP receiver started on port {port}...");
while (true)
{
// 接收数据
var result = await udpClient.ReceiveAsync();
var message = Encoding.UTF8.GetString(result.Buffer);
Console.WriteLine($"Received: {message}");
// 保存到Redis
await SaveToRedisAsync(message);
}
}
}
private async Task SaveToRedisAsync(string message)
{
var key = $"udp:{Guid.NewGuid()}"; // 生成唯一键
await _redis.StringSetAsync(key, message);
Console.WriteLine($"Saved to Redis: {key}");
}
}
```
**2. 定时同步到SQL Server**
```csharp
using System;
using System.Data.SqlClient;
using System.Threading;
using System.Threading.Tasks;
using StackExchange.Redis;
public class DataSyncService
{
private readonly IDatabase _redis;
private readonly string _sqlConnectionString;
private Timer _timer;
public DataSyncService(string redisConnectionString, string sqlConnectionString)
{
var redis = ConnectionMultiplexer.Connect(redisConnectionString);
_redis = redis.GetDatabase();
_sqlConnectionString = sqlConnectionString;
}
public void StartSync(int intervalInSeconds)
{
_timer = new Timer(SyncData, null, TimeSpan.Zero, TimeSpan.FromSeconds(intervalInSeconds));
Console.WriteLine($"Data sync started with interval {intervalInSeconds} seconds.");
}
private async void SyncData(object state)
{
try
{
// 获取所有Redis键
var keys = _redis.Multiplexer.GetServer(_redis.Multiplexer.GetEndPoints()[0]).Keys(pattern: "udp:*");
foreach (var key in keys)
{
// 从Redis获取数据
var message = await _redis.StringGetAsync(key);
Console.WriteLine($"Syncing: {key} -> {message}");
// 保存到SQL Server
await SaveToSqlServerAsync(key, message);
// 从Redis删除已同步的数据
await _redis.KeyDeleteAsync(key);
Console.WriteLine($"Deleted from Redis: {key}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Sync failed: {ex.Message}");
}
}
private async Task SaveToSqlServerAsync(string key, string message)
{
using (var connection = new SqlConnection(_sqlConnectionString))
{
await connection.OpenAsync();
var command = new SqlCommand(
"INSERT INTO UdpMessages (Key, Message) VALUES (@Key, @Message)", connection);
command.Parameters.AddWithValue("@Key", key);
command.Parameters.AddWithValue("@Message", message);
await command.ExecuteNonQueryAsync();
Console.WriteLine($"Saved to SQL Server: {key}");
}
}
}
```
**3. 主程序**
```csharp
using System;
using System.Threading.Tasks;
public class Program
{
public static async Task Main(string[] args)
{
var redisConnectionString = "localhost";
var sqlConnectionString = "Server=your_server;Database=your_db;Integrated Security=True;";
// 启动UDP接收器
var udpReceiver = new UdpReceiver(redisConnectionString);
var udpTask = udpReceiver.StartAsync(5000); // 监听5000端口
// 启动数据同步服务
var syncService = new DataSyncService(redisConnectionString, sqlConnectionString);
syncService.StartSync(intervalInSeconds: 60); // 每60秒同步一次
// 保持程序运行
await udpTask;
}
}
```
**代码说明**
- **UDP数据接收**:
- 使用 `UdpClient` 监听指定端口,接收数据并保存到Redis。
- **Redis数据存储**:
- 使用 `StackExchange.Redis` 将接收到的数据存储为键值对。
- **定时同步到SQL Server**:
-
使用 `Timer` 定时从Redis读取数据并同步到SQL Server。
-
同步完成后,从Redis中删除已同步的数据。
- **SQL Server表结构**:
- 假设SQL Server中有一个表 `UdpMessages`,结构如下:
```sql
CREATE TABLE UdpMessages (
Id INT PRIMARY KEY IDENTITY,
Key NVARCHAR(100) NOT NULL,
Message NVARCHAR(MAX) NOT NULL
);
```
**运行步骤**
- **启动RabbitMQ**:
- 确保Redis和SQL Server服务已启动。
- **运行程序**:
- 运行程序后,UDP接收器开始监听端口,数据同步服务定时将数据从Redis同步到SQL Server。
- **测试UDP数据接收**:
- 使用工具(如 `netcat`)发送UDP数据到指定端口:
```bash
echo "Hello, UDP!" | nc -u 127.0.0.1 5000
```
**优化建议**
- **批量同步**:
- 使用 `SqlBulkCopy` 批量插入数据,提高同步效率。
- **错误处理**:
- 添加重试机制,确保数据同步的可靠性。
- **性能监控**:
- 使用日志记录同步状态和性能指标。
通过以上代码,您可以实现一个完整的UDP数据接收、Redis缓存和SQL Server同步的系统。