在Application中集成Microsoft Translator服务之优化

Posted 王起帆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Application中集成Microsoft Translator服务之优化相关的知识,希望对你有一定的参考价值。

在一篇文章中我们已经实现了功能,但是一个明显的问题是响应时间非常长,用户体验非常糟糕,这篇文章将带你找出问题所在并进行优化

为了找出追魁祸首,这里使用 System.Diagnostics.Stopwatch来对我们的应用程序执行进行计时。

修改一下TranslatorController中Translate中的代码

  System.Diagnostics.Stopwatch watch1 = new System.Diagnostics.Stopwatch();
            System.Diagnostics.Stopwatch watch2 = new System.Diagnostics.Stopwatch();
            watch1.Start();
            AdmAuthentication adm = new AdmAuthentication("zuin", "Ursm3pji3Fcha+70plJFrAbHT/Y00F7vyKdXlWLusmc=");
           
            
            watch1.Stop();
            watch2.Start();

            string uri = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=" + System.Web.HttpUtility.UrlEncode(text) + "&from=" + from + "&to=" + to;
            string authToken = "Bearer" + " " + adm.token.access_token;

            HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(uri);
            httpWebRequest.Headers.Add("Authorization", authToken);
            WebResponse response = null;
            try
            {
                response = httpWebRequest.GetResponse();
                using (Stream stream = response.GetResponseStream())
                {
                    System.Runtime.Serialization.DataContractSerializer dcs = new System.Runtime.Serialization.DataContractSerializer(Type.GetType("System.String"));
                    string translation = (string)dcs.ReadObject(stream);
                    watch2.Stop();
                    return Json(translation+"获取令牌的时间是"+watch1.Elapsed.ToString()+"  获取翻译的时间是"+watch2.Elapsed.ToString());
                }
            }
            catch
            {
                watch2.Stop();
                string code = "fail";
                return Json(code);
            }

我们来看看效果

从上面的数据可以看出获取翻译的时间非常短,一般不会超过半分钟,而获取令牌的时间非常长,而且不稳定,这个是优化的关键

一.使用cookie和session来保存令牌

这里以cookie为例

    string access_token = "";
            if (this.HttpContext.Request.Cookies["authToken"]==null)
            {
                AdmAuthentication adm = new AdmAuthentication("zuin", "Ursm3pji3Fcha+70plJFrAbHT/Y00F7vyKdXlWLusmc=");
                access_token = adm.token.access_token;


                HttpCookie cookie = new HttpCookie("authToken");
                cookie.Value = adm.token.access_token;
                cookie.Expires = DateTime.Now.AddMinutes(9);
                Response.Cookies.Add(cookie);
            }
            else
            {
                access_token = this.HttpContext.Request.Cookies["authToken"].ToString();
            }


 string authToken = "Bearer" + " " + access_token;

 来看看效果

使用cookie可以达到我们的目的,不用每次都去获取令牌,可以在cookie里面直接获取,令牌在10分钟内有效,所以不需要考虑安全问题。对带宽的影响也不是很大。

 二.使用HttpRuntime来缓存令牌

cookie和session的数据之内给单独用户使用,独乐乐不如众乐乐,数据应该拿出来共享,这里使用HttpRuntime来解决这个问题,首先修改下代码、

 string access_token = "";
            if (this.HttpContext.Cache["authToken"]==null)
            {
                AdmAuthentication adm = new AdmAuthentication("zuin", "Ursm3pji3Fcha+70plJFrAbHT/Y00F7vyKdXlWLusmc=");
                access_token = adm.token.access_token;
                this.HttpContext.Cache.Insert("authToken", access_token, null, DateTime.Now.AddMinutes(9), TimeSpan.Zero);
            }
            else
            {
                access_token = this.HttpContext.Cache["authToken"].ToString();
            }

  之前使用Edge浏览器,这次使用火狐浏览器看看效果

显然也是达到了我们的目的

NOTE:

Cache 类不能在 ASP.NET 应用程序外使用。它是为在 ASP.NET 中用于为 Web 应用程序提供缓存而设计和测试的。在其他类型的应用程序(如控制台应用程序或 Windows 窗体应用程序)中,ASP.NET 缓存可能无法正常工作。(来自MSDN)

这个cache之能被我们的ASP.NET应用程序访问,依然无法取代memcached等分布式缓存。

 三.使用memcached分布式缓存

首先需要在电脑安装memcached(http://memcached.org/)

在项目中引用Memcached.ClientLibrary.dll,log4net.dll,ICSharpCode.SharpZipLib.dll,Commons.dll四个程序集

封装一下操控memcached的

public class MmHelper
    {
        private MemcachedClient client;
        public MmHelper()
        {
            string[] ips = System.Configuration.ConfigurationManager.AppSettings["MemcachedServers"].Split(\',\');

            SockIOPool pool = SockIOPool.GetInstance();
            pool.SetServers(ips);
            pool.Initialize();

            client = new MemcachedClient();
            client.EnableCompression = true;
        }

        public bool Set(string key, object value, DateTime expiryTime)
        {
            return client.Set(key, value, expiryTime);
        }

        public object Get(string key)
        {
            return client.Get(key);
        }

        public bool Delete(string key)
        {
            return client.Delete(key);
        }
    }

修改前面的代码

   MmHelper mm = new MmHelper();
            if (mm.Get("authToken")==null)
            {
                AdmAuthentication adm = new AdmAuthentication("zuin", "Ursm3pji3Fcha+70plJFrAbHT/Y00F7vyKdXlWLusmc=");
                access_token = adm.token.access_token;
                mm.Set("authToken", access_token, DateTime.Now.AddMinutes(9));
            }
            else
            {
                access_token = mm.Get("authToken").ToString();
            }

现在来看看效果

ok!

以上是关于在Application中集成Microsoft Translator服务之优化的主要内容,如果未能解决你的问题,请参考以下文章

在Application中集成Microsoft Translator服务之优化

在Application中集成Microsoft Translator服务之获取访问令牌

在Application中集成Microsoft Translator服务之使用http获取服务

在 ASP.NET 4.6.1 项目中集成 Microsoft.Extensions.DependencyInjection

在 Microsoft Visual Studio 中的 x86 C++ 应用程序中集成犰狳

跨平台应用集成(在ASP.NET Core MVC 应用程序中集成 Microsoft Graph)