【应用场景】

同一个用户身份使用多线程调用WebAPI接口,默认是排队的,只有前面接口返回了结果,后一个接口才能继续处理 ;这是IIS的机制,相同的 session id的时候超过一定数量的时候会出现排队现象,但是我们可以使用多用户多站点调用来提高调用效率。



【注意事项】

线程不是越多越好,应根据具体应用场景和系统资源来权衡。



【案例演示】

使用4个用户2个站点调用WebAPI接口保存客户。


【实现步骤】

<1>基于帖子https://vip.kingdee.com/article/650363039794871552?productLineId=1&isKnowledge=2&lang=zh-CN的代码做修改。 

<2>代码如下。

using Newtonsoft.Json; using System; using System.Collections.Concurrent; using System.Linq; using System.Threading.Tasks; namespace Zlf.WebApiDemo {     class Program     {         const string AppId = "296988_47aD5+sL6kH8WV8u6eSASbzLTs7aRoLL";         const string AppSecret = "566381bd78d64d83b6a2f9be05cdd01e";         const string K3cloudUrl = "http://localhost/k3cloud/";//k3cloud站点         const string K3cloudAppUrl = "http://localhost/k3cloudApp/";//k3cloudapp站点         const string DbId = "67468ad9fb6464";         static readonly ConcurrentDictionary<string, WebApiHttpInvoke> DicUser = new ConcurrentDictionary<string, WebApiHttpInvoke>();         static int _currentUserIndex = -1;         static void Main(string[] args)         {         //本示例创建了4个用户实例,其中用了2个站点。这里采用异步的方式调用,确保4个实例是可以并行同步数据。             Console.WriteLine("保存开始..");             DicUser["demo_k3cloud"] = new   WebApiHttpInvoke(K3cloudUrl, DbId, "demo", AppId,AppSecret);             DicUser["demo2_k3cloudapp"] = new WebApiHttpInvoke(K3cloudUrl, DbId, "demo2", AppId,AppSecret);             DicUser["demo3_k3cloud"] = new WebApiHttpInvoke(K3cloudAppUrl, DbId, "demo3", AppId,AppSecret);             DicUser["demo4_k3cloudapp"] = new WebApiHttpInvoke(K3cloudAppUrl, DbId, "demo4", AppId,AppSecret);             Task[] tasks = new Task[10];             for (int i = 0; i < tasks.Length; i++)             {                 int n = i;                 tasks[i] = Task.Run(() => DoSave(string.Format("20241129-{0}", n)));             }             Task.WhenAll(tasks).Wait();             Console.WriteLine("全部保存完成..");             Console.ReadLine();         }         private static void DoSave(string billNo)          {             var instance = GetInstance();             instance.Save("BD_Customer", billNo, CreateJson(billNo));         }         /// <summary>         /// 按轮询方式获取WebApiHttpInvoke实例         /// </summary>         /// <returns></returns>         private static WebApiHttpInvoke GetInstance()         {             _currentUserIndex = (_currentUserIndex + 1) % DicUser.Count;             var kvp = DicUser.ElementAt(_currentUserIndex);             if (kvp.Key == null || kvp.Value == null)             {                 throw new Exception("GetInstance error");             }             return kvp.Value;         }         private static string CreateJson(string billNo)         {             var data = new             {                 IsVerifyBaseDataField = true,                 Model = new                 {                     FCreateOrgId = new                     {                         FNumber = "100"                     },                     FNumber = billNo,                     FUseOrgId = new                     {                         FNumber = "100"                     },                     FName = billNo,                     FCOUNTRY = new                     {                         FNumber = "China"                     },                     FIsDefPayer = false,                     FIsGroup = false,                     FCustTypeId = new                     {                         FNumber = "KHLB001_SYS"                     },                     FTRADINGCURRID = new                     {                         FNumber = "PRE001"                     },                     FTRANSLEADTIME = 0                 }             };             return JsonConvert.SerializeObject(data);         }     } }

<2>WebApiHttpInvoke.cs代码如下。

using Kingdee.BOS.WebApi.Client; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Zlf.WebApiDemo {     class WebApiHttpInvoke     {         private readonly string _dbId, _userName, _appId, _appSecret;         private readonly object _obj = new object();         private readonly K3CloudApiClient _client;         private bool _isLogin;         public WebApiHttpInvoke(string url, string dbId, string userName, string appId, string appSecret)         {             this._dbId = dbId;             this._userName = userName;             this._appId = appId;             this._appSecret = appSecret;             _client = new K3CloudApiClient(url, 10 * 60);//超时时间设为10分钟         }         //保存单据         public void Save(string formId, string billNo, string data, bool isRetry = false)         {             string saveResult = _client.Save(formId, data);             var responseStatus = JObject.Parse(saveResult)["Result"]["ResponseStatus"];             var isSuccess = responseStatus["IsSuccess"].Value<bool>();             if (!isSuccess)             {                 var msgCode = responseStatus["MsgCode"].Value<int>();                 if (msgCode == 1)//会话丢失,可能未登录或者过期了                 {                     if (isRetry)                     {                         return;                     }                     _isLogin = false;                     Login(); //重新登录                     Save(formId, billNo, data, true);                 }                 else                 {                     //暂存单据                     Console.WriteLine("保存失败,返回结果:{0}", saveResult);                 }             }             else             {                 Console.WriteLine("保存成功,billNo={0} ", billNo);             }         }         /// <summary>         /// 登录操作         /// </summary>         /// <returns></returns>         private bool Login()         {             lock (_obj)             {                 if (!_isLogin)                 {                     //使用第三方系统登录授权                     var loginResult = _client.LoginByAppSecret(this._dbId, this._userName, this._appId, this._appSecret, 2052);                     if (loginResult.Contains("response_error"))                     {                         //系统异常,包括账套id错误                         throw new Exception(loginResult);                     }                     var resultType = JObject.Parse(loginResult)["LoginResultType"].Value<int>();                     if (resultType == 1)                     {                         _isLogin = true;                         return true;                     }                     throw new Exception(loginResult);                 }             }             return true;         }     } }

【功能验证】

<1>运行代码。

上传图片


<1>查看WebAPI日志,确认可以多用户并发保存。


上传图片


上一篇:WebAPI一次登录多次调用示例   下一篇:启用webapi日志

作者:cyoukon

来源:金蝶云社区

原文链接:https://vip.kingdee.com/knowledge/650388592971234560?specialId=650386937144032256&productLineId=1&isKnowledge=2&lang=zh-CN

著作权归作者所有。未经允许禁止转载,如需转载请联系作者获得授权。


标签: none

添加新评论