diff --git a/ChordInstaller/ChordInstaller.csproj b/ChordInstaller/ChordInstaller.csproj
index acba05fd..5d9b6853 100644
--- a/ChordInstaller/ChordInstaller.csproj
+++ b/ChordInstaller/ChordInstaller.csproj
@@ -30,7 +30,7 @@
Chord
true
publish.htm
- 93
+ 94
1.2.0.%2a
false
true
diff --git a/DigitalPlatform.MessageClient/MessageConnection.cs b/DigitalPlatform.MessageClient/MessageConnection.cs
index a4cf2986..842526ae 100644
--- a/DigitalPlatform.MessageClient/MessageConnection.cs
+++ b/DigitalPlatform.MessageClient/MessageConnection.cs
@@ -555,9 +555,10 @@ public virtual async Task ConnectAsync()
}
catch (HttpRequestException ex)
{
+ // InnerException
MessageResult result = new MessageResult();
result.Value = -1;
- result.ErrorInfo = ex.Message;
+ result.ErrorInfo = ExceptionUtil.GetExceptionMessage(ex); // ex.Message;
result.String = "HttpRequestException";
return result;
}
diff --git a/TestClient1/TestClient1.csproj b/TestClient1/TestClient1.csproj
index 97dc679d..53472929 100644
--- a/TestClient1/TestClient1.csproj
+++ b/TestClient1/TestClient1.csproj
@@ -45,8 +45,39 @@
..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll
+
+
+ ..\packages\System.IO.4.3.0\lib\net462\System.IO.dll
+ True
+ True
+
+
+ ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll
+ True
+ True
+
+
+ ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll
+ True
+ True
+
+
+ ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll
+ True
+ True
+
+
+ ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll
+ True
+ True
+
+
+ ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll
+ True
+ True
+
diff --git a/TestClient1/app.config b/TestClient1/app.config
index 55d9a585..58eb8c1b 100644
--- a/TestClient1/app.config
+++ b/TestClient1/app.config
@@ -1,191 +1,193 @@
-
-
-
-
-
-
-
-
-
- http://localhost:8083/dp2mserver
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- getPatronInfo
-
-
- searchPatron
-
-
-
-
-
- 0,100
-
-
-
-
-
- bind
-
-
-
-
-
-
-
-
-
-
-
- single
-
-
- xml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- False
-
-
-
-
-
- {}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ http://localhost:8083/dp2mserver
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ getPatronInfo
+
+
+ searchPatron
+
+
+
+
+
+ 0,100
+
+
+
+
+
+ bind
+
+
+
+
+
+
+
+
+
+
+
+ single
+
+
+ xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ False
+
+
+
+
+
+ {}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dp-library b/dp-library
index aa89e521..7c720d93 160000
--- a/dp-library
+++ b/dp-library
@@ -1 +1 @@
-Subproject commit aa89e5216a997d2600c00002c2644cbc50d643c5
+Subproject commit 7c720d93adddb3212df9325f29c3caaf683312d3
diff --git a/dp2Capo/Properties/AssemblyInfo.cs b/dp2Capo/Properties/AssemblyInfo.cs
index 638e5b2a..112ebc2e 100644
--- a/dp2Capo/Properties/AssemblyInfo.cs
+++ b/dp2Capo/Properties/AssemblyInfo.cs
@@ -32,8 +32,8 @@
// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.52.*")]
-[assembly: AssemblyFileVersion("1.52.0.0")]
+[assembly: AssemblyVersion("1.53.*")]
+[assembly: AssemblyFileVersion("1.53.0.0")]
// 1.1 (2016/6/26) 首次使用了版本号
// 1.2 (2016/9/14) 管理线程中会不断重试连接 dp2mserver,并将此情况写入日志
@@ -84,11 +84,12 @@
// 登录时,把对 dp2library 的 Login() 调用用记录锁保护起来,令针对同一个用户名(和实例名)的登录从并发变为顺次调用,避免突然在 dp2libraryChannelPool 中分配很多 dp2library 通道(可能导致通道配额耗尽)
// 1.44 (2022/5/24) SIP Server ScStatus() API 改用 capo 账户。Login() API 增加检查危险权限功能
// 1.45 (2022/6/20) SIP Server 增加了 LoginCache 机制,避免高密度的 Login() 请求引起 dp2library CPU 耗用居高不下
-// 1.46 (2022/9/16) SetInfo() API 中增加了 setBiblioInfo 子功能
+// 1.46 (2022/9/16) 点对点 SetInfo() API 中增加了 setBiblioInfo 子功能
// 1.47 (2022/9/20) SIP Server PatronInformation() API 兑现了 summary 参数,并限制了每次获得 AU 等字段的总个数为 10 (这是一个实验性的数字,后面会再调整)
// 1.48 (2022/9/23) SIP Server PatronInformation() API 中优化了为在借册获得机构代码的速度。要求最新版 3.129 dp2library 配合
// 1.49 (2022/9/26) SIP Server PatronInformation() API 执行中途会检测 TCP 连接是否被前端 Close,如果被 Close 的话会尽快中断高耗能的处理
// PatronInformation() API 可以用 AC!testing 字段内容来模拟测试长时操作,便于前端验证 Close
// 1.50 (2022/9/27) SIP Server 大约每一分钟清理一次 dp2library version 缓存
// 1.51 (2022/9/29) SIP Server 借书或者续借限制了当前读者在借册 50 册以下。如果达到或超过 50 册,则不允许借书了,只能还书
-// 1.52 (2022/10/1) chordInstaller 中 dp2capo 实例对话框中,为 SIP 通道增加了一个“在借册数限额”参数。默认为 -1,表示不限制
\ No newline at end of file
+// 1.52 (2022/10/1) chordInstaller 中 dp2capo 实例对话框中,为 SIP 通道增加了一个“在借册数限额”参数。默认为 -1,表示不限制
+// 1.53 (2022/10/19) 点对点 Search() API 增加 getItemInfoEx 子功能,等同于 dp2library API 的 GetItemIinfo() API
\ No newline at end of file
diff --git a/dp2Capo/ServerConnection.cs b/dp2Capo/ServerConnection.cs
index ed7af2f0..5db7829b 100644
--- a/dp2Capo/ServerConnection.cs
+++ b/dp2Capo/ServerConnection.cs
@@ -1482,6 +1482,12 @@ void SearchAndResponse(SearchRequest searchParam)
return;
}
+ if (searchParam.Operation == "getItemInfoEx")
+ {
+ GetSingleItemInfo(searchParam);
+ return;
+ }
+
if (searchParam.Operation == "getBrowseRecords")
{
GetBrowseRecords(searchParam);
@@ -2692,6 +2698,179 @@ void GetSystemParameter(SearchRequest searchParam)
strErrorCode));
}
+ static string RemovePrefixParameter(string text, string prefix)
+ {
+ if (string.IsNullOrEmpty(text))
+ return text;
+ var list = text.Split(',').ToList();
+ for (int i = 0; i < list.Count; i++)
+ {
+ string s = list[i];
+ if (s == prefix || s.StartsWith(prefix + ":"))
+ {
+ list.RemoveAt(i);
+ i--;
+ }
+ }
+
+ return StringUtil.MakePathList(list, ",");
+ }
+
+ // 2022/10/19
+ void GetSingleItemInfo(SearchRequest searchParam)
+ {
+ string strError = "";
+ string strErrorCode = "";
+ IList records = new List();
+
+ if (string.IsNullOrEmpty(searchParam.FormatList) == true)
+ {
+ strError = "FormatList 不应为空";
+ goto ERROR1;
+ }
+
+ try
+ {
+ LibraryChannel channel = GetChannel(searchParam.LoginInfo);
+ try
+ {
+ string strItemDbType = searchParam.DbNameList;
+ if (string.IsNullOrEmpty(strItemDbType))
+ strItemDbType = "item";
+ else if (strItemDbType == "entity")
+ strItemDbType = "item";
+
+ string strItemFormat = searchParam.FormatList;
+ if (string.IsNullOrEmpty(strItemFormat))
+ strItemFormat = "xml";
+ else
+ {
+ // 从 strItemFormat 中去掉 biblioFormat:xxx 部分
+ strItemFormat = RemovePrefixParameter(strItemFormat, "biblioFormat");
+ }
+
+ string strBiblioFormat = StringUtil.GetParameterByPrefix(searchParam.FormatList, "biblioFormat");
+
+ long lRet = channel.GetItemInfo(
+ strItemDbType,
+ searchParam.QueryWord,
+ searchParam.Filter, // filter 负责发送 strItemXml
+ strItemFormat,
+ out string strItemResult,
+ out string strItemRecPath,
+ out byte[] item_timestamp,
+ strBiblioFormat,
+ out string strBiblioResult,
+ out string strBiblioRecPath,
+ out strError);
+
+ /*
+ public long GetItemInfo(
+ // // DigitalPlatform.Stop stop,
+ string strItemDbType,
+ string strBarcode,
+ string strItemXml,
+ string strResultType,
+ out string strResult,
+ out string strItemRecPath,
+ out byte[] item_timestamp,
+ string strBiblioType,
+ out string strBiblio,
+ out string strBiblioRecPath,
+ out string strError)
+ */
+
+ /*
+ long lRet = channel.GetReaderInfo(// null,
+ searchParam.QueryWord,
+ searchParam.FormatList,
+ out results,
+ out strRecPath,
+ out baTimestamp,
+ out strError);
+ */
+ strErrorCode = channel.ErrorCode.ToString();
+ if (lRet == -1 || lRet == 0)
+ {
+ if (lRet == 0
+ || (lRet == -1 && channel.ErrorCode == DigitalPlatform.LibraryClient.localhost.ErrorCode.NotFound))
+ {
+ // 没有命中
+ TryResponseSearch(
+ new SearchResponse(
+ searchParam.TaskID,
+ 0,
+ 0,
+ this.dp2library.LibraryUID,
+ records,
+ strError, // 出错信息大概为 not found。
+ strErrorCode));
+ return;
+ }
+ goto ERROR1;
+ }
+
+ records.Clear();
+ // 返回册记录
+ {
+ DigitalPlatform.Message.Record item = new DigitalPlatform.Message.Record();
+ item.RecPath = strItemRecPath;
+ item.Data = strItemResult;
+ if (item_timestamp != null)
+ item.Timestamp = ByteArray.GetHexTimeStampString(item_timestamp);
+ item.Format = strItemFormat;
+ records.Add(item);
+ }
+ // 返回书目记录
+ if (string.IsNullOrEmpty(strBiblioFormat) == false)
+ {
+ DigitalPlatform.Message.Record biblio = new DigitalPlatform.Message.Record();
+ biblio.RecPath = strBiblioRecPath;
+ biblio.Data = strBiblioResult;
+ biblio.Format = strBiblioFormat;
+ records.Add(biblio);
+ }
+
+ long batch_size = -1;
+ bool bRet = TryResponseSearch(
+ searchParam.TaskID,
+ records.Count,
+ 0,
+ this.dp2library.LibraryUID,
+ records,
+ "",
+ strErrorCode,
+ ref batch_size);
+ Console.WriteLine("ResponseSearch called " + records.Count.ToString() + ", bRet=" + bRet);
+ if (bRet == false)
+ return;
+ }
+ finally
+ {
+ this.ReturnChannel(channel);
+ }
+ }
+ catch (Exception ex)
+ {
+ AddErrorLine("GetSingleItemInfo() 出现异常: " + ex.Message);
+ strError = "GetSingleItemInfo() 异常:" + ExceptionUtil.GetDebugText(ex);
+ goto ERROR1;
+ }
+
+ this.AddInfoLine("search and response end");
+ return;
+ ERROR1:
+ // 报错
+ TryResponseSearch(
+ new SearchResponse(
+ searchParam.TaskID,
+ -1,
+ 0,
+ this.dp2library.LibraryUID,
+ records,
+ strError,
+ strErrorCode));
+ }
void GetPatronInfo(SearchRequest searchParam)
{