大家好。
背景:
我正在开发一个 ASP.NET Web 应用程序项目。门票通过网络应用程序出售,当然,门票可以 PDF 和 pkpass 格式获得。在生成 pkpass 票证时,您需要在票证上附加一个密钥和一个证书(这是 2 个文件)并将其发送给 Apple 进行验证。实际上,NuGet 库就是这样做的。 这是我遇到的问题:
描述原因需要很长时间,但归根结底是我们不得不切换到PassSharp库,因此我们重写了整个请求代码。使用新库时,网站负载很重,一些 pkpass 停止验证(每天 0 到 10 件 +/-),并且它们无法在苹果设备上打开。原因:一天几次,2个用户在同一秒内完成支付,第二个线程无法访问文件。我们得到一个 IOException。代码示例:
Набрали объект pass (не важно для задачи), далее:
using (var myStream = new MemoryStream())
{
string fileNamePK = String.Format(часть алгоритма генерации имени+ @"{0}.pkpass", часть алгоритма генерации имени; //не спрашивайте
//Проблема вот здесь:
byte[] appleCert = File.ReadAllBytes(currDir + "//" + appleCert);
byte[] appleCertKey = File.ReadAllBytes(currDir + "//" + appleKey);
PassWriter.WriteToStream(pass, myStream,
new X509Certificate2(appleCert),
new X509Certificate2(appleCertKey,appleCertPass, X509KeyStorageFlags.Exportable));
FileStream file = new FileStream(FileNamePath + "\\" + fileNamePK, FileMode.CreateNew, FileAccess.Write);
myStream.WriteTo(file);
file.Close();
myStream.Close();
ResultListPass += fileNamePK + ";";
}
而且发生这种情况的可能性似乎很小......
我发现的所有示例都建议执行以下操作:
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
StreamReader fsr = new StreamReader(fs);
byteArrey = fsr.CurrentEncoding.GetBytes(fsr.ReadToEnd());
但是 X509Certificate2 接受一个字节数组,并且类似的方法旨在读取文本信息,无论我如何尝试绕过它(例如,像这样:CurrentEncoding.GetBytes) - 没有结果。此类操作后的字节数组不正确。为了在 byteArrey 之后检查,我什至添加了行 var test = File.ReadAllBytes(filePath); - 字节数组不同。理想的选择是在应用程序级别缓存这些文件并从内存中获取它们,但我不知道该怎么做......显然,这需要在 IIS 级别完成,但同样 - 我不知道不知道怎么做。如果我弄清楚了 - 如何访问它们?请帮助任何可以...
如果文件很小,则可以使用 InMemoryCache。
尝试对代码的有问题的部分使用锁定
或读取字节并将它们缓存到静态变量中(如果它们不更改)。
在使用PassSharp库一段时间并尝试了各种选项(包括上面列出的选项)之后,我们得出的结论是问题不在于实现,而在于库本身,因为无论我采取何种行动,症状都会持续存在。显然它不适合这种加载的应用程序。
接下来 - 我回到dotnet-passbook 库并试图找出它停止工作的原因。经过相当详细的分析,我发现安装的库缺少库的 GitHub 存储库中的一些方法。由于重新安装库并没有解决问题,我使用来自 GitHub 的代码在我们的应用程序中重新定义了 PassGenerator 和 PassGeneratorRequest 类,这要归功于该解决方案至今仍然有效。