Esempio n. 1
0
        public static async Task <PresentResult> FetchRecords(ZClientChannel channel,
                                                              long count)
        {
            var ok = channel.Enter();

            try
            {
                if (ok == false)
                {
                    return new PresentResult
                           {
                               Value     = -1,
                               ErrorInfo = "通道已被占用",
                               ErrorCode = "channelInUse"
                           }
                }
                ;

                return(await _fetchRecords(channel, count).ConfigureAwait(false));
            }
            finally
            {
                channel.Exit();
            }
        }
Esempio n. 2
0
        static async Task <PresentResult> _fetchRecords(ZClientChannel channel,
                                                        long count)
        {
            if (channel._resultCount - channel._fetched > 0)
            {
                return(await channel.ZClient.Present(
                           "default",
                           channel._fetched,
                           Math.Min((int)channel._resultCount - channel._fetched, (int)count),
                           10,
                           "F",
                           channel.TargetInfo.PreferredRecordSyntax).ConfigureAwait(false));
            }

            return(new PresentResult {
                Value = -1, ErrorInfo = "已经获取完成"
            });
        }
Esempio n. 3
0
        // 从 XML 文件中装载服务器配置信息
        public NormalResult LoadServer(string xmlFileName,
                                       Marc8Encoding marc8Encoding)
        {
            this.Clear();

            this.XmlFileName = xmlFileName;

            XmlDocument dom = new XmlDocument();

            try
            {
                dom.Load(xmlFileName);
            }
            catch (Exception ex)
            {
                return(new NormalResult {
                    Value = -1, ErrorInfo = ex.Message
                });
            }

            XmlNodeList servers = dom.DocumentElement.SelectNodes("server");

            foreach (XmlElement server in servers)
            {
                var result = ZServerUtil.GetTarget(server,
                                                   marc8Encoding,
                                                   out TargetInfo targetInfo);
                if (result.Value == -1)
                {
                    return(result);
                }
                ZClientChannel channel = new ZClientChannel
                {
                    ServerName = server.GetAttribute("name"),
                    ZClient    = new ZClient(),
                    TargetInfo = targetInfo,
                    Enabled    = ZServerListDialog.IsEnabled(server.GetAttribute("enabled"), true)
                };
                _channels.Add(channel);
            }

            return(new NormalResult());
        }
Esempio n. 4
0
        // 针对一个特定 Z30.50 服务器发起检索
        async Task <NormalResult> SearchOne(
            ZClientChannel channel,
            UseCollection useList,
            IsbnSplitter isbnSplitter,
            string strQueryWord,
            int nMax,
            string strFromStyle,
            string strMatchStyle,
            delegate_searchCompleted searchCompleted,
            delegate_presentCompleted presentCompleted)
        {
            var ok = channel.Enter();

            try
            {
                if (ok == false)
                {
                    return(new NormalResult
                    {
                        Value = -1,
                        ErrorInfo = "通道已被占用",
                        ErrorCode = "channelInUse"
                    });
                }

                var             _targetInfo     = channel.TargetInfo;
                IsbnConvertInfo isbnconvertinfo = new IsbnConvertInfo
                {
                    IsbnSplitter = isbnSplitter,
                    ConvertStyle =
                        (_targetInfo.IsbnAddHyphen == true ? "addhyphen," : "")
                        + (_targetInfo.IsbnRemoveHyphen == true ? "removehyphen," : "")
                        + (_targetInfo.IsbnForce10 == true ? "force10," : "")
                        + (_targetInfo.IsbnForce13 == true ? "force13," : "")
                        + (_targetInfo.IsbnWild == true ? "wild," : "")
                        // TODO:
                        + (_targetInfo.IssnForce8 == true ? "issnforce8," : "")
                };

                string strQueryString = "";
                {
                    // 创建只包含一个检索词的简单 XML 检索式
                    // 注:这种 XML 检索式不是 Z39.50 函数库必需的。只是用它来方便构造 API 检索式的过程
                    string strQueryXml = BuildQueryXml(strQueryWord, strFromStyle);
                    // 将 XML 检索式变化为 API 检索式
                    var result = ZClient.ConvertQueryString(
                        useList,
                        strQueryXml,
                        isbnconvertinfo,
                        out strQueryString);
                    if (result.Value == -1)
                    {
                        searchCompleted?.Invoke(channel, new SearchResult(result));
                        var final_result = new NormalResult {
                            Value = result.Value, ErrorInfo = result.ErrorInfo
                        };
                        if (result.ErrorCode == "notFound")
                        {
                            final_result.ErrorCode = "useNotFound";
                        }
                        return(final_result);
                    }
                }

REDO_SEARCH:
                {
                    // return Value:
                    //      -1  出错
                    //      0   成功
                    //      1   调用前已经是初始化过的状态,本次没有进行初始化
                    // InitialResult result = _zclient.TryInitialize(_targetInfo).GetAwaiter().GetResult();
                    // InitialResult result = _zclient.TryInitialize(_targetInfo).Result;
                    InitialResult result = await channel.ZClient.TryInitialize(_targetInfo);

                    if (result.Value == -1)
                    {
                        searchCompleted?.Invoke(channel, new SearchResult(result));
                        // TODO: 是否继续向后检索其他 Z39.50 服务器?
                        return(new NormalResult {
                            Value = -1, ErrorInfo = "Initialize error: " + result.ErrorInfo
                        });
                    }
                }

                // result.Value:
                //		-1	error
                //		0	fail
                //		1	succeed
                // result.ResultCount:
                //      命中结果集内记录条数 (当 result.Value 为 1 时)
                SearchResult search_result = await channel.ZClient.Search(
                    strQueryString,
                    _targetInfo.DefaultQueryTermEncoding,
                    _targetInfo.DbNames,
                    _targetInfo.PreferredRecordSyntax,
                    "default");

                if (search_result.Value == -1 || search_result.Value == 0)
                {
                    if (search_result.ErrorCode == "ConnectionAborted")
                    {
                        // 自动重试检索
                        goto REDO_SEARCH;
                    }
                }

                searchCompleted?.Invoke(channel, search_result);
                channel._resultCount = search_result.ResultCount;

                if (search_result.Value == -1 ||
                    search_result.Value == 0 ||
                    search_result.ResultCount == 0)
                {
                    return(new NormalResult());  // continue
                }
                var present_result = await _fetchRecords(channel, PresentBatchSize /*10*/);

                presentCompleted?.Invoke(channel, present_result);

                if (present_result.Value != -1)
                {
                    channel._fetched += present_result.Records.Count;
                }

                return(new NormalResult());
            }
            finally
            {
                channel.Exit();
            }
        }