|
@@ -0,0 +1,104 @@
|
|
|
+
|
|
|
+using CallCenter.Calls;
|
|
|
+using Microsoft.Extensions.DependencyInjection;
|
|
|
+using Microsoft.Extensions.Hosting;
|
|
|
+using Microsoft.Extensions.Options;
|
|
|
+using SqlSugar;
|
|
|
+using System.Net;
|
|
|
+using XF.Domain.Cache;
|
|
|
+
|
|
|
+namespace CallCenter.CacheManager
|
|
|
+{
|
|
|
+ public class CallRecordManager : BackgroundService
|
|
|
+ {
|
|
|
+ private readonly IServiceScopeFactory _serviceScopeFactory;
|
|
|
+
|
|
|
+ public CallRecordManager(IServiceScopeFactory serviceScopeFactory)
|
|
|
+ {
|
|
|
+ _serviceScopeFactory = serviceScopeFactory;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
|
|
+ {
|
|
|
+ var time = TimeSpan.FromMinutes(1);
|
|
|
+ await Task.Delay(time, stoppingToken);
|
|
|
+ while(!stoppingToken.IsCancellationRequested)
|
|
|
+ {
|
|
|
+ using var scope = _serviceScopeFactory.CreateScope();
|
|
|
+ var _callRecordRepository = scope.ServiceProvider.GetService<ICallRecordRepository>();
|
|
|
+ //var _recordSettings = scope.ServiceProvider.GetConfigValue<RecordSettings>();
|
|
|
+ var _recordSettings = _serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService<IOptionsSnapshot<RecordSettings>>();
|
|
|
+ //TODO 查询所有没有下载语音文件的记录
|
|
|
+ var canDownList = await _callRecordRepository!.QueryAsync(x => !x.IsDown);
|
|
|
+ if (canDownList != null)
|
|
|
+ {
|
|
|
+ //TODO 下载语音文件
|
|
|
+ foreach (var item in canDownList)
|
|
|
+ {
|
|
|
+ //分隔数据
|
|
|
+ if (!string.IsNullOrEmpty(item.Recording))
|
|
|
+ {
|
|
|
+ string dir = item.Recording.Split("/")[0];
|
|
|
+ string filename = item.Recording.Split("/")[1];
|
|
|
+ //string url = "";
|
|
|
+ string url = _recordSettings.Value.Remote + item.Recording;//远程地址
|
|
|
+ string localfile = "Recorder/" + dir + "/"; //本地地址
|
|
|
+ long startPosition = 0;//上次下载的文件起始位置
|
|
|
+ FileStream writeStream;//写入本地文件流对象
|
|
|
+ if (File.Exists(localfile+filename))
|
|
|
+ {
|
|
|
+ writeStream = File.OpenWrite(localfile + filename);
|
|
|
+ startPosition = writeStream.Length; //获取已经下载的长度
|
|
|
+ writeStream.Seek(startPosition, SeekOrigin.Current);//本地文件写入位置定位
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (!File.Exists(localfile))
|
|
|
+ {
|
|
|
+ System.IO.Directory.CreateDirectory(localfile);
|
|
|
+ }
|
|
|
+ writeStream = new FileStream(localfile + filename, FileMode.Create);//保存
|
|
|
+ startPosition = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(url);// 打开网络连接
|
|
|
+
|
|
|
+ if (startPosition>0)
|
|
|
+ {
|
|
|
+ myRequest.AddRange((int)startPosition); //设置Range值,与上面的writeStream.Seek用意相同,是为了定义远程文件读取位置
|
|
|
+ }
|
|
|
+ Stream readStream = myRequest.GetResponse().GetResponseStream();// 向服务器请求,获得服务器的回应数据流
|
|
|
+ byte[] btArray = new byte[512];// 定义一个字节数据,用来向readStream读取内容和向writeStream写入内容
|
|
|
+ int contentSize = readStream.Read(btArray, 0, btArray.Length);// 向远程文件读第一次
|
|
|
+
|
|
|
+ while (contentSize > 0)// 如果读取长度大于零则继续读
|
|
|
+ {
|
|
|
+ writeStream.Write(btArray, 0, contentSize);// 写入本地文件
|
|
|
+ contentSize = readStream.Read(btArray, 0, btArray.Length);// 继续向远程文件读取
|
|
|
+ }
|
|
|
+
|
|
|
+ //关闭流
|
|
|
+ writeStream.Close();
|
|
|
+ readStream.Close();
|
|
|
+
|
|
|
+ //成功 修改状态
|
|
|
+ item.IsDown = true;
|
|
|
+ await _callRecordRepository.UpdateAsync(item);
|
|
|
+ }
|
|
|
+ catch
|
|
|
+ {
|
|
|
+ writeStream.Close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ await Task.Delay(time,stoppingToken);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|