http://www.cnblogs.com/xxxteam/archive/2013/04/15/3023159.html

利用thrift实现js与C#通讯的例子

关键字:thrift js javascript C# Csharp webservice

1.为什么要用thrift js C#?

1.1 首先,js 通过 thrift 访问C#,实际上是一种c/s模式。thrift是通信工具,js是客户端,C#是服务端。

1.2 使用js直接与thrift server通信。让web开发变得更简单。如果使用Web Service,你需要自己去实现C/S两端的序列化与反序列化操作,还需要自行处理异常,降低了开发效率。而thrift则会自动生成两端的操作类,你只需要处理方法内部的逻辑即可。

1.3 js直接与thrift server通信,可以提高性能,并且用C#开发server,开发效率也非常高。(那些web service弱爆了)

1.4 当然,我们不能只看到优点。用这种方法也有比较明显的缺点:如果使用web service,则网页与web service可以封装在一个工程里,部署到IIS上后,可以存在于一个网站内。而使用了thrift后,你还需要手动管理thrift程序。包括:

1.4.1 你需要拥有服务端的绝对控制权,比如,你可以直接登录服务器的操作系统上进行操作。因此,如果你只有一个网页空间,则不适合这种方法。当然,你也可以用web service里绑定thrift,但这样你又需要自己手动进行序列化与反序列操作,而且两次转换让性能更低,有违初衷

1.4.2 给thrift server程序增加自动启动,与监视程序,来完成thrift的崩溃后自动重启。

2.环境

Win7 - VS2012 - .net 4.0 C# 控制台工程(用来承载thrift)

Win7 - VS2012 - .net 4.0 C# Web工程(用来调试js,超方便)

3.步骤(以下步骤,对于小白来说,有些困难。QQ讨论群:23152359 )

3.1 去thrift官方下载thrift库,目前是0.9.0。

3.2 去thrift官方下载编译好的win下的thrift编译器,是一个exe文件。

3.3 写一个数据结构定义文件。我在这里只是用了服务,没有定义自定义数据结构。

data.txt:

1 service UserStorage
2 {
3 i32 Sum( 1: i32 arg_number1, 2: i32 arg_number2),
4 string GetString()
5 }

3.4 命令行下,用thrift编译器,对它进行编译:
        run.bat:

1 thrift-0.9.0.exe --gen csharp data.txt
2 thrift-0.9.0.exe --gen js data.txt
3 pause

3.5 建立一个名字为CSharpServer的C#控制台工程,.net 4.0的。

3.6 为这个工程,添加现有项目:thrift库目录\thrift-0.9.0\lib\csharp\src\Thrift.csproj,然后引用这个项目。

3.7 把thrift编译出来的UserStorage.cs(在gen-csharp目录里),拖动到解决方案管理器里的CSharpServer项目的根目录下,UserStorage.cs与Program.cs应该在同一级。

3.8 在CSharpServer项目里创建一个UserStorage的处理类UserStorageHandle.cs:(它应该与UserStorage.cs与Program.cs在同一级)

 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace CSharpServer
7 {
8 public class UserStorageHandle : UserStorage.Iface
9 {
10
11 public UserStorageHandle()
12 {
13 ;
14 }
15
16 public int Sum(int arg_number1, int arg_number2)
17 {
18 int result = arg_number1 + arg_number2;
19 Console.WriteLine(DateTime.Now.ToString() + " 收到请求:Sum,参数:arg_number1 = " + arg_number1.ToString() + ",arg_number2 = " + arg_number2.ToString() + ",返回:result = " + result.ToString());
20 return result;
21 }
22
23 private static int Counter = 0;
24
25 public string GetString()
26 {
27 int currentCounter = System.Threading.Interlocked.Increment(ref UserStorageHandle.Counter);
28 Console.WriteLine(DateTime.Now.ToString() + " 收到请求:GetString,参数:没有,返回:result = \"thrift is OK : " + currentCounter.ToString() + "\"");
29 return "thrift is OK : " + currentCounter.ToString();
30 }
31
32 }
33 }

3.9 主程序Program.cs:

 1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using Thrift.Transport;
6 using Thrift.Protocol;
7 using Thrift.Server;
8 using System.Net;
9
10 namespace CSharpServer
11 {
12 class Program
13 {
14 private static HttpListener httpListener = null;
15 private static THttpHandler httpServer = null;
16
17 static void Main(string[] args)
18 {
19 string serviceUrl = "http://localhost:99/";
20 try
21 {
22 UserStorageHandle handle = new UserStorageHandle();
23 UserStorage.Processor processor = new UserStorage.Processor(handle);
24 TProtocolFactory protocolFactory = new TJSONProtocol.Factory();
25
26 Program.httpServer = new THttpHandler(processor, protocolFactory);
27
28 Program.httpListener = new HttpListener();
29 Program.httpListener.Prefixes.Add(serviceUrl);
30 Program.httpListener.Start();
31 IAsyncResult result = Program.httpListener.BeginGetContext(new AsyncCallback(WebRequestCallback), null);
32 Console.WriteLine("Thrift 服务成功启动,网址是 " + serviceUrl);
33 }
34 catch (System.Exception ex)
35 {
36 Console.WriteLine("发生错误:" + ex.Message);
37 Console.WriteLine("按回车键退出");
38 Console.ReadLine();
39 return;
40 }
41 Console.WriteLine("若需结束程序,请直接关闭窗口,或按回车。");
42 Console.ReadLine();
43 }
44
45 public static void WebRequestCallback(IAsyncResult result)
46 {
47 if (Program.httpListener == null)
48 {
49 Console.WriteLine("发生错误:HttpListener已经被关闭");
50 Console.WriteLine("按回车键退出");
51 Console.ReadLine();
52 return;
53 }
54
55 HttpListenerContext httpListenerContext = Program.httpListener.EndGetContext(result);
56
57 Program.httpListener.BeginGetContext(new AsyncCallback(WebRequestCallback), null);
58
59 Program.httpServer.ProcessRequest(httpListenerContext);
60 }
61
62 }
63 }

3.10 按F5,启动CSharpServer项目。

3.11 新开一个VS2012(内存不够的赶快去买),建立一个叫JsProject的C# .net 4.0 Web空工程。

3.12 去jquery官网下载jquery-1.9.1.js(mini版也行,随便)

3.13 把thrift编译的js文件data_types.js与UserStorage.js,thrift库的js库文件(thrift库目录\thrift-0.9.0\lib\js\thrift.js),以及刚下载的jq文件jquery-1.9.1.js,全部拖动到解决方案资源管理器的JsProject项目的根目录下:

data_types.js \ jquery-1.9.1.js \ thrift.js \ UserStorage.js 应该与Web.config在同一级。

3.14 在根目录下创建一个Test.html文件,Test.html 应该与Web.config在同一级:

Test.html:

 1 <!DOCTYPE html>
2 <html xmlns="http://www.w3.org/1999/xhtml">
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5 <title></title>
6 <script type="text/javascript" src="jquery-1.9.1.js"></script>
7 <script type="text/javascript" src="data_types.js"></script>
8 <script type="text/javascript" src="thrift.js"></script>
9 <script type="text/javascript" src="UserStorage.js"></script>
10
11 <script>
12 $(document).ready(function ()
13 {
14 var debugPosation = 0;
15 try
16 {
17 var transport = new Thrift.Transport("http://localhost:99");
18 var protocol = new Thrift.Protocol(transport);
19 var client = new UserStorageClient(protocol);
20
21 var result_GetString = client.GetString();
22 var result_Sum = client.Sum(255, 322);
23 }
24 catch (e)
25 {
26 alert("出错鸟:" + e.message);
27 }
28 });
29 </script>
30 </head>
31 <body>
32 </body>
33 </html>

3.15 给Test.html的 “ var debugPosation = 0; ” 这一行,下断点,然后F5,就可以看到效果了。

4.注意两个问题

4.1 由于web服务一般都是80端口,如果thrift端口与其不同,js在访问时会遇到跨域问题,js报错e.message = "拒绝访问"。但是,对于传说中的windows server,完全没有问题,因为,windows server支持.net的传说中的端口复用功能!因此,假设部署后,网站的iis的url为:http://www.baidu.com/XXX,则你最好给thrift server留一个二级域名,比如 http://www.baidu.com/ThriftService ,把这个留给thrift。最后,直接把thrift server的监听url,设置为这个 http://www.baidu.com/ThriftService 就OK了,不会有端口冲突问题,因为win Server + .net 支持tcp端口复用!!!! 如果你的网站的url还带有端口,比如 http://www.baidu.com:9999/XXX,或者IP形式:http://11.2.33.44:9999/XXX,则thriftservice也需要与它的端口相同,比如:http://www.baidu:9999/ThriftService 或 http://11.2.33.44:9999/ThriftService 。问,网站端口与thriftserver端口并不是80,而是9999,有没有问题?答:木有问题,端口复用功能依然会发挥作用。不过,端口复用技术,是通过让IIS和ThriftServer,把端口监听的工作,都交给System.exe去做,所有如果要做防火墙,要注意一下。防火墙参见这个帖子:http://www.cnblogs.com/xxxteam/archive/2013/04/22/3036082.html

4.2 网址的最后一个斜杠问题。js访问thrift service,网址最后一个字符,是不带斜杠的。比如http://www.baidu.com/XXX/,这个就是错误的,因为最后一个是斜杠。应该去掉最后一个斜杠,更正为: http://www.baidu.com/XXX  。而ThriftServer的监听网址,则最后一个斜杠是不能省去的。坑爹吧?当然了,这个问题可能会因为日后的补丁被修正,所以大家自己留意一下。

5.为什么不能使用js + thrift server方案?

看到这里傻眼了吧?上面白忙活大半天,但最后居然发现这个方案有问题?是的。

5.1 Thrift的定义,仅仅是一个通信工具,它不是能7*24运行的类似于iis这种服务提供程序。相对于wcf来说,thrift简单,所以高效。但正是因为它简单,所以它缺少很多在复杂网络环境下充当服务端的功能。在实际使用中,如果把它当成webService Server,则经常出问题。而且很多问题是try catch也抓不住,直接导致宿主程序崩溃的。所以,如果希望构建一个稳定的webService server,还是使用wcf之类的稳定方案为妙。

不过,这并不是说thrift就不行。thrift可以在系统内部来进行数据传输,但绝对不能放在外部。

5.2 js + thrift不支持异步调用!原因是,js只有以ajax方式进行远程服务调用才具有异步功能,但thrift封装的远程服务调用,不是ajax方式的。

其他更多问题详见 http://www.cnblogs.com/xxxteam/archive/2013/04/24/3040839.html

 
分类: C#

thrift js javascript C# Csharp webservice的更多相关文章

  1. Atitit.js javascript的rpc框架选型

    Atitit.js javascript的rpc框架选型 1. Dwr1 2. 使用AJAXRPC1 2.2. 数据类型映射表1 3. json-rpc轻量级远程调用协议介绍及使用2 3.1. 2.3 ...

  2. Immutable.js – JavaScript 不可变数据集合

    不可变数据是指一旦创建就不能被修改的数据,使得应用开发更简单,允许使用函数式编程技术,比如惰性评估.Immutable JS 提供一个惰性 Sequence,允许高效的队列方法链,类似 map 和 f ...

  3. Js(javaScript)的闭包原理

    问题?什么是js(javaScript)的闭包原理,有什么作用? 一.定义 官方解释:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.  小编 ...

  4. 【转】Eclipse去除js(JavaScript)验证错误

    这篇文章主要是对Eclipse去除js(JavaScript)验证错误进行了介绍.在Eclipse中,js文件常常会报错.可以通过如下几个步骤解决 第一步:去除eclipse的JS验证:将window ...

  5. Atitit.js javascript异常处理机制与java异常的转换 多重catc hDWR 环境 .js exception process Vob7

    Atitit.js javascript异常处理机制与java异常的转换 多重catc hDWR 环境 .js exception processVob7 1. 1. javascript异常处理机制 ...

  6. Atitit.js javascript异常处理机制与java异常的转换.js exception process Voae

    Atitit.js javascript异常处理机制与java异常的转换.js exception processVoae 1. 1. javascript异常处理机制 1 2. 2. Web前后台异 ...

  7. atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97

    atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97 1. 实现html5化界面的要解决的策略1 1.1. Js交互1 1.2. 动态参 ...

  8. Atitit. servlet 与 IHttpHandler  ashx  listen 和HttpModule的区别与联系 原理理论 架构设计   实现机制    java php c#.net js javascript  c++ python

    Atitit. servlet 与 IHttpHandler  ashx  listen 和HttpModule的区别与联系 原理理论 架构设计   实现机制    java php c#.net j ...

  9. Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle

    Atitit. 数据约束 校验 原理理论与 架构设计 理念模式java php c#.net js javascript mysql oracle 1. 主键1 2. uniq  index2 3.  ...

随机推荐

  1. 嵌入在网站上Flash播放机(2)

    然后在一个博客.这里有一个flash嵌入式播放器.这是公司内部使用的flash播放机,支持格更多款式,同时支持swf格视频播放的类型. 以下是页面嵌入代码: <link rel="st ...

  2. bsh for android : 北京

    beanshell : bjtime.bsh source("/sdcard/com.googlecode.bshforandroid/extras/bsh/android.bsh" ...

  3. matlab学习------------普通dialog对话框,错误对话框errordlg,警告对话框warndlg

    Dialog对话框 语法: h = dialog('PropertyName',PropertyValue,...) 对话框的默认属性 WindowStyle的值:   {normal} | moda ...

  4. 怎么样ubuntu 64 11.04 在执行32位程序

    上网一查非常多的信息,头发上的今天ubuntu 64 11.04 在执行32位程序安装ia32-libs包,可执行例如,下面的命令.但提示无法安装 apt-get install ia32-libs ...

  5. win2008服务器部署系统前需要做的一些工作

    一.打开.net framework及IIS管理器 win2008系统自带是有.net framework3.5的,但是默认该功能是没有开启的,需要手动开启(和win7一样).点击控制面板->程 ...

  6. jquery animate的递归调用

    去年面试过一家做网站的 公司,看了一下他们的案例,看懂一个蛮有意思的 ,一个房地产的官网,是用flash做的.感觉不错. 于是,闲暇之际,简单的jquery 模仿做了一下.下面是我的效果图.脚本也没啥 ...

  7. python使用smtplib库和smtp.qq.com邮件服务器发送邮件(转)

    使用qq的邮件服务器需要注意的两个地方主要是: 1.协议问题 使用465端口 SSL 协议 2.口令问题 出现SMTPAuthenticationError 主要的原因就是口令和帐号信息不对,这里我们 ...

  8. Android日志收集功能设计和实施报告(总)

    几乎所有的应用程序开发者都知道"用户体验"重视,为了增强用户体验是从全面的监测和报告制度密不可分,在这些日志(控制Crash报告)是主要的问题跟踪和解决工具. 日志上报系统.首先看 ...

  9. 变化Android系统属性SystemProperties.set(&quot;sys.powerctl&quot;, &quot;shutdown&quot;)关机分析

    基本介绍: 从以前的博客中提到,我们,最后,通过关机过程变化Android关机属性(SystemProperties.java由JNI呼叫接入系统属性),当然,我们也能adb命令变化Android系统 ...

  10. LinkedBlockingQueue的put,add跟offer的区别(转)

    LinkedBlockingQueue的put,add和offer的区别 最近在学习<<Java并发编程实践>>,有很多java.util.concurrent包下的新类.Li ...