private static void Zserver_InitializeLogin(object sender, InitializeLoginEventArgs e) { ZServerChannel zserver_channel = (ZServerChannel)sender; string strInstanceName = zserver_channel.SetProperty().GetKeyValue("i_n"); if (strInstanceName == null) { string strErrorText = "通道中 实例名 '" + strInstanceName + "' 尚未初始化"; ZManager.Log?.Error(strErrorText); e.Result = new Result { Value = -1, ErrorInfo = strErrorText }; return; } Instance instance = FindInstance(strInstanceName); if (instance == null) { e.Result = new Result { Value = -1, ErrorInfo = "实例名 '" + strInstanceName + "' 不存在" }; return; } // result.Value: // -1 登录出错 // 0 登录未成功 // 1 登录成功 string strUserName = zserver_channel.SetProperty().GetKeyValue("i_u"); string strPassword = zserver_channel.SetProperty().GetKeyValue("i_p"); LoginInfo login_info = new LoginInfo { UserName = strUserName, Password = strPassword }; LibraryChannel library_channel = instance.MessageConnection.GetChannel(login_info); try { string strParameters = ""; if (login_info.UserType == "patron") { strParameters += ",type=reader"; } strParameters += ",client=dp2capo|" + "0.01"; long lRet = library_channel.Login(strUserName, strPassword, strParameters, out string strError); e.Result.Value = (int)lRet; e.Result.ErrorInfo = strError; } finally { instance.MessageConnection.ReturnChannel(library_channel); } }
private static void Zserver_SetChannelProperty(object sender, SetChannelPropertyEventArgs e) { ZServerChannel zserver_channel = (ZServerChannel)sender; List <string> parts = StringUtil.ParseTwoPart(e.Info.m_strID, "@"); string strUserName = parts[0]; string strInstanceName = parts[1]; string strPassword = e.Info.m_strPassword; // 匿名登录情形 if (string.IsNullOrEmpty(strUserName)) { Instance instance = FindInstance(strInstanceName); if (instance == null) { e.Result = new Result { Value = -1, ErrorCode = "InstanceNotFound", ErrorInfo = "以用户名 '" + e.Info.m_strID + "' 中包含的实例名 '" + strInstanceName + "' 没有找到任何实例" }; return; } // 如果定义了允许匿名登录 if (String.IsNullOrEmpty(instance.zhost.AnonymousUserName) == false) { strUserName = instance.zhost.AnonymousUserName; strPassword = instance.zhost.AnonymousPassword; } else { e.Result = new Result { Value = -1, ErrorCode = "AnonymouseLoginDenied", ErrorInfo = "不允许匿名登录" }; return; } } // 让 channel 从此携带 Instance Name zserver_channel.SetProperty().SetKeyValue("i_n", strInstanceName); zserver_channel.SetProperty().SetKeyValue("i_u", strUserName); zserver_channel.SetProperty().SetKeyValue("i_p", strPassword); Debug.Assert(e.Result != null, ""); }
private static void Zserver_GetZConfig(object sender, GetZConfigEventArgs e) { ZServerChannel zserver_channel = (ZServerChannel)sender; #if NO List <string> parts = StringUtil.ParseTwoPart(e.Info.m_strID, "@"); string strInstanceName = parts[1]; #endif string strInstanceName = zserver_channel.SetProperty().GetKeyValue("i_n"); if (strInstanceName == null) { string strError = "通道中 实例名 '" + strInstanceName + "' 尚未初始化"; ZManager.Log.Error(strError); e.ZConfig = null; e.Result.ErrorInfo = strError; return; } Instance instance = FindInstance(strInstanceName); if (instance == null) { e.ZConfig = null; e.Result.ErrorInfo = "以用户名 '" + e.Info.m_strID + "' 中包含的实例名 '" + strInstanceName + "' 没有找到任何实例"; return; } // 让 channel 携带 Instance Name // zserver_channel.SetProperty().SetKeyValue("i_n", strInstanceName); e.ZConfig = new ZConfig { AnonymousUserName = instance.zhost.AnonymousUserName, AnonymousPassword = instance.zhost.AnonymousPassword, }; }
// 取出先前记忆的全局结果集名列表 // parameters: // bRemove 是否在返回前自动删除 key_object 集合中的值 static List <string> GetResultSetNameList(ZServerChannel zserver_channel, bool bRemove = false) { lock (zserver_channel) { if (!(zserver_channel.SetProperty().GetKeyObject("r_n") is List <string> names)) { return(new List <string>()); } else { if (bRemove) { zserver_channel.SetProperty().SetKeyObject("r_n", null); } } return(names); } }
// 记忆全局结果集名 static void MemoryResultSetName(ZServerChannel zserver_channel, string resultset_name) { if (!(zserver_channel.SetProperty().GetKeyObject("r_n") is List <string> names)) { names = new List <string>(); zserver_channel.SetProperty().SetKeyObject("r_n", names); } if (names.IndexOf(resultset_name) == -1) { names.Add(resultset_name); } // 如果结果集名数量太多,就要开始删除 if (names.Count > MAX_RESULTSET_COUNT) { FreeGlobalResultSets(zserver_channel, names); } }
static void FreeGlobalResultSets(ZServerChannel zserver_channel, List <string> names) { string strInstanceName = zserver_channel.SetProperty().GetKeyValue("i_n"); if (strInstanceName == null) { string strError = "通道中 实例名 '" + strInstanceName + "' 尚未初始化"; ZManager.Log?.Error(strError); } Instance instance = FindInstance(strInstanceName); if (instance == null) { string strError = "实例名 '" + strInstanceName + "' 不存在"; // 写入错误日志 ZManager.Log?.Error(strError); return; } // TODO: 交给 Instance 释放 instance.AddGlobalResultSets(names); #if NO LibraryChannel library_channel = instance.MessageConnection.GetChannel(null); try { foreach (string name in names) { // TODO: 要是能用通配符来删除大量结果集就好了 long lRet = library_channel.GetSearchResult("", 0, 0, "@remove:" + name, "zh", out DigitalPlatform.LibraryClient.localhost.Record[] searchresults, out string strError); if (lRet == -1) { // 写入错误日志 return; } } } finally { instance.MessageConnection.ReturnChannel(library_channel); } #endif }
private static void Zserver_PresentGetRecords(object sender, PresentGetRecordsEventArgs e) { string strError = ""; ZServerChannel zserver_channel = (ZServerChannel)sender; string strInstanceName = zserver_channel.SetProperty().GetKeyValue("i_n"); if (strInstanceName == null) { strError = "通道中 实例名 '" + strInstanceName + "' 尚未初始化"; ZManager.Log.Error(strError); goto ERROR1; } Instance instance = FindInstance(strInstanceName); if (instance == null) { strError = "实例名 '" + strInstanceName + "' 不存在"; goto ERROR1; } string strResultSetName = e.Request.m_strResultSetID; if (String.IsNullOrEmpty(strResultSetName) == true) { strResultSetName = "default"; } long lStart = e.Request.m_lResultSetStartPoint - 1; long lNumber = e.Request.m_lNumberOfRecordsRequested; int MAX_PRESENT_RECORD = 100; // 限制每次 present 的记录数量 if (lNumber > MAX_PRESENT_RECORD) { lNumber = MAX_PRESENT_RECORD; } DiagFormat diag = null; List <RetrivalRecord> records = new List <RetrivalRecord>(); string strUserName = zserver_channel.SetProperty().GetKeyValue("i_u"); string strPassword = zserver_channel.SetProperty().GetKeyValue("i_p"); LoginInfo login_info = new LoginInfo { UserName = strUserName, Password = strPassword }; LibraryChannel library_channel = instance.MessageConnection.GetChannel(login_info); try { // 全局结果集名 string resultset_name = MakeGlobalResultSetName(zserver_channel, strResultSetName); ResultSetLoader loader = new ResultSetLoader(library_channel, resultset_name, "id,xml,timestamp") { Start = lStart, BatchSize = Math.Min(10, lNumber) }; int i = 0; int nSize = 0; foreach (DigitalPlatform.LibraryClient.localhost.Record dp2library_record in loader) { if (i >= lNumber) { break; } if (i == 0) { e.TotalCount = loader.TotalCount; if (lStart >= loader.TotalCount) { DiagFormat diag1 = null; ZProcessor.SetPresentDiagRecord(ref diag1, 13, // Present request out-of-range "Present 所请求的起始偏移位置 " + lStart + " 超过结果集中记录总数 " + loader.TotalCount); e.Diag = diag1; return; } } { // 解析出数据库名和ID string strDbName = dp2StringUtil.GetDbName(dp2library_record.Path); string strRecID = dp2StringUtil.GetRecordID(dp2library_record.Path); // 如果取得的是xml记录,则根元素可以看出记录的marc syntax,进一步可以获得oid; // 如果取得的是MARC格式记录,则需要根据数据库预定义的marc syntax来看出oid了 string strMarcSyntaxOID = GetMarcSyntaxOID(instance, strDbName); RetrivalRecord record = new RetrivalRecord { m_strDatabaseName = strDbName }; // 根据书目库名获得书目库属性对象 BiblioDbProperty prop = instance.zhost.GetDbProperty( strDbName, false); int nRet = GetIso2709Record(dp2library_record, e.Request.m_elementSetNames, prop != null ? prop.AddField901 : false, prop != null ? prop.RemoveFields : "997", zserver_channel.SetProperty().MarcRecordEncoding, out byte[] baIso2709, out strError); /* * // 测试记录群中包含诊断记录 * if (i == 1) * { * nRet = -1; * strError = "测试获取记录错误"; * } */ if (nRet == -1) { record.m_surrogateDiagnostic = new DiagFormat { m_strDiagSetID = "1.2.840.10003.4.1", m_nDiagCondition = 14, // system error in presenting records m_strAddInfo = strError }; } else if (nRet == 0) { record.m_surrogateDiagnostic = new DiagFormat { m_strDiagSetID = "1.2.840.10003.4.1", m_nDiagCondition = 1028, // record deleted m_strAddInfo = strError }; } else if (String.IsNullOrEmpty(strMarcSyntaxOID) == true) { // 根据数据库名无法获得marc syntax oid。可能是虚拟库检索命中记录所在的物理库没有在 capo.xml 中配置。 record.m_surrogateDiagnostic = new DiagFormat { m_strDiagSetID = "1.2.840.10003.4.1", m_nDiagCondition = 109, // database unavailable // 似乎235:database dos not exist也可以 m_strAddInfo = "根据数据库名 '" + strDbName + "' 无法获得 marc syntax oid" }; } else { record.m_external = new External { m_strDirectRefenerce = strMarcSyntaxOID, m_octectAligned = baIso2709 }; } nSize += record.GetPackageSize(); if (i == 0) { // 连一条记录也放不下 if (nSize > zserver_channel.SetProperty().ExceptionalRecordSize) { Debug.Assert(diag == null, ""); ZProcessor.SetPresentDiagRecord(ref diag, 17, // record exceeds Exceptional_record_size "记录尺寸 " + nSize.ToString() + " 超过 Exceptional_record_size " + zserver_channel.SetProperty().ExceptionalRecordSize.ToString()); lNumber = 0; break; } } else { if (nSize >= zserver_channel.SetProperty().PreferredMessageSize) { // 调整返回的记录数 lNumber = i; break; } } records.Add(record); } i++; } } catch (Exception ex) { strError = "获取结果集时出现异常: " + ex.Message; goto ERROR1; } finally { instance.MessageConnection.ReturnChannel(library_channel); } e.Records = records; e.Diag = diag; return; ERROR1: { DiagFormat diag1 = null; ZProcessor.SetPresentDiagRecord(ref diag1, 2, // temporary system error strError); e.Diag = diag1; // e.Result = new ZClient.SearchResult { Value = -1, ErrorInfo = strError }; return; } }
private static void Zserver_SearchSearch(object sender, SearchSearchEventArgs e) { ZServerChannel zserver_channel = (ZServerChannel)sender; string strInstanceName = zserver_channel.SetProperty().GetKeyValue("i_n"); if (strInstanceName == null) { string strErrorText = "通道中 实例名 '" + strInstanceName + "' 尚未初始化"; ZManager.Log?.Error(strErrorText); e.Result = new DigitalPlatform.Z3950.ZClient.SearchResult { Value = -1, ErrorInfo = strErrorText }; return; } Instance instance = FindInstance(strInstanceName); if (instance == null) { e.Result = new DigitalPlatform.Z3950.ZClient.SearchResult { Value = -1, ErrorInfo = "实例名 '" + strInstanceName + "' 不存在" }; return; } // 根据逆波兰表构造出 dp2 系统检索式 // return: // -1 error // 0 succeed int nRet = Z3950Utility.BuildQueryXml( instance.zhost, e.Request.m_dbnames, e.Request.m_rpnRoot, zserver_channel.SetProperty().SearchTermEncoding, out string strQueryXml, out string strError); if (nRet == -1) { DiagFormat diag = null; ZProcessor.SetPresentDiagRecord(ref diag, 2, // temporary system error strError); e.Diag = diag; e.Result = new ZClient.SearchResult { Value = -1, ErrorInfo = strError }; return; } string strUserName = zserver_channel.SetProperty().GetKeyValue("i_u"); string strPassword = zserver_channel.SetProperty().GetKeyValue("i_p"); LoginInfo login_info = new LoginInfo { UserName = strUserName, Password = strPassword }; LibraryChannel library_channel = instance.MessageConnection.GetChannel(login_info); try { // 全局结果集名 string resultset_name = MakeGlobalResultSetName(zserver_channel, e.Request.m_strResultSetName); // 进行检索 long lRet = library_channel.Search( strQueryXml, resultset_name, "", // strOutputStyle out strError); /* * // 测试检索失败 * lRet = -1; * strError = "测试检索失败"; * */ if (lRet == -1) { DiagFormat diag = null; ZProcessor.SetPresentDiagRecord(ref diag, 2, // temporary system error strError); e.Diag = diag; e.Result = new ZClient.SearchResult { Value = -1, ErrorInfo = strError }; return; } else { // 记忆结果集名 MemoryResultSetName(zserver_channel, resultset_name); e.Result = new ZClient.SearchResult { ResultCount = lRet }; } } finally { instance.MessageConnection.ReturnChannel(library_channel); } }