谈一谈调用远程服务的几种实现方式

前言:

      也许在我们过往的项目开发过程当中,或多或少都会遇到过针对于现有系统信息进行整合,使用的需求,或是调用人家接口或是给人家提供服务,今天就简单的和大家一起分享一些可用的远程调用服务的方法:

1.webservice方法

       Web Service 是一种新的web应用程序分支,他们是自包含、自描述、模块化的应用,可以发布、定位、通过web调用。Web Service可以执行从简单的请求到复杂商务处理的任何功能。一旦部署以后,其他Web Service应用程序可以发现并调用它部署的服务。 
  实际上,WebService的主要目标是跨平台的可互操作性。为了达到这一目标,WebService完全基于XML(可扩展标记语言)、XSD(XMLSchema)等独立于平台、独立于软件供应商的标准,是创建可互操作的、分布式应用程序的新平台。

我相信大家都会有很多使用webservice的经验,首先说一下在web端调用同域下的webservice:

新建一个webservice,默认生成一个helloWord方法:

    [WebMethod]

    public string HelloWorld() {

        return "Hello World";

    }

之后我没在web端调用此服务:

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

    <title></title>

    <script src="jquery.js" type="text/javascript"></script>



    <script type="text/javascript">

        $(function () {

            $('#a_post').click(function () {

                postFun();

            });

        });



        function postFun() {

            $.ajax({

                type: "POST",  //访问WebService使用post方式请求

                contentType: "application/xml",   //WebService会返回json类型

                url: "http://localhost:1719/testaaa/MyWebService.asmx/HelloWorld", //调用WebService的地址和方法名称组合

                dataType: "xml",

                success: function (data) {

                    var html;

                    if (typeof data == "string") {

                        html = new ActiveXObject("Microsoft.XMLDOM");

                        html.loadXML(data);

                    }

                    else {

                        html = data;

                    }

                    var $result = $(html).find("string");

                    var result = $result.text();

                    alert(result);

                }

            })

        }

    </script>

</head>

<body>

<input type="button" id="a_post" value="获取"/>

</body>

</html>

于是我们可以得到如下:

谈一谈调用远程服务的几种实现方式

谈一谈调用远程服务的几种实现方式

说明我们在web端调用同域下webservice成功。

于是我们会想是否可以以这种方法调用远程(不同域)下的webservice呢?

我明确的告诉你非常不容易,我一般的处理方式是在C#后台代码中调用这个服务,web端调用同域下的那个调用远程服务的后台服务就可以了,这其实是一种服务代理的方法,如果大家有什么好的实现web端调用远程webservice的方法,希望大家能够告诉我哦。

于是大家就会想:难道真的没有实现跨域调用服务的方法了吗?

方法还是有的,听我慢慢道来:

2:Jsonp

      什么是JSONP  JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。

Jsonp原理:

      由于我们知道<script>标签是可以跨域的,所以我们就以动态生成<script>脚本的形式实现跨域请求:

首先在客户端注册一个callback, 然后把callback的名字传给服务器。

此时,服务器先生成 json 数据。 

然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.

最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)

由于jsonp传送的形式是json形式,所以我们修改远程的服务:

using System;

using System.Web;



public class Handler : IHttpHandler {



    public void ProcessRequest(HttpContext context) {

        context.Response.ContentType = "text/plain";

        string callback = context.Request["callback"];

        string response = string.Format("'value1':'{0}','value2':'{1}'", context.Request.QueryString["p1"], context.Request.QueryString["p2"]);

        string call = callback + "({" + response + "})";

        context.Response.Write(call); 

    }

 

    public bool IsReusable {

        get {

            return false;

        }

    }



}

web端调用:

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <title></title>

    <script src="jquery.js" type="text/javascript"></script>

    <script type="text/javascript">

        $(document).ready(function () {

            $('#a_post').click(function () {

                postFun();

            });

        });



        var postFun = function () {

            jQuery.ajax({

                type: "get",

                //url: "Jsonp_learn.aspx",

                url: "http://localhost:1719/testaaa/Handler.ashx",

                dataType: "jsonp",

                jsonp: "callback",

                data: "p1=1&p2=2",

                success: function (msg) {

                    alert("value1:" + msg.value1 + " value2:" + msg.value2);

                }

            });

        }

    </script>

</head>

<body>

<input type="button" id="a_post" value="获取"/>

</body>

</html>

实现的结果:

谈一谈调用远程服务的几种实现方式

OK,至此我们已经可以实现了我们的一些要求,当然程序员的特点就是永远希望找到最好的东西,并且与一切不简单,不美好的东西作斗争,我们思考一下以上两种实现方法的特点:

webservice:是以soap协议,xml形式调用的,web端调用我们需要将结果处理成xml;

jsonp:这是程序员思考的结晶,可是并没有一些官方的标准;

其实我们回想:何必这么麻烦不就是请求一个结果吗,一个字符串不久可以了?

3.restful

      RESTful Wcf是一种基于Http协议的服务架构风格。 相较 WCF、WebService 使用 SOAP、WSDL、WS-* 而言,几乎所有的语言和网络平台都支持 HTTP 请求。

RESTful的几点好处:

1、简单的数据通讯方式,基于HTTP协议。避免了使用复杂的数据通讯方式。

2、避免了复杂的客户端代理。

3、直接通过URI资源定向即可把服务暴露给调用者。

REST 架构风格的流行。REST是一种简洁的设计风格,通过URL来设计系统,以URI来抽象各种资源,以HTTP协议的PUT,DELETE,GET,POST来对应对资源的各种操作。

于是我们决定用这种:既简单,由有一定的规范值得参考:

我们的实现可以依照wcf,具体实现大家可以google之,我们简单说一下.net的实现restful的比较好的方法webAPI:

我们通过vs傻瓜式的就建立了一个webapi:

Model:

public class TestUseMode

    {

        public string ModeKey{get;set;}

        public string ModeValue { get; set; }

        

    }

Controller:

MVC WebAPI中的Controllers和普通MVC的Controllers类似,不过不再继承于Controller,而改为继承API的ApiController,一个Controller可以包含多个Action,这些Action响应请求的方法与Global中配置的路由规则有关,在后面结束Global时统一说明.

 public class TestController : ApiController

    {

        public static List<TestUseMode> allModeList = new List<TestUseMode>();







        public IEnumerable<TestUseMode> GetAll()

        {

            return allModeList;

        }



        public IEnumerable<TestUseMode> GetOne(string key)

        {

            return allModeList.FindAll((mode) => { if (mode.ModeKey.Equals(key)) return true; return false; });

        }



        public bool PostNew(TestUseMode mode)

        {

            allModeList.Add(mode);

            return true;

        }



        public int Delete(string key)

        {

            return allModeList.RemoveAll((mode) => { if (mode.ModeKey == key) return true; return false; });

        }



        public int DeleteAll()

        {

            return allModeList.RemoveAll((mode) => { return true; });

        }



        public int PutOne(string key, string value)

        {

            List<TestUseMode> upDataList = allModeList.FindAll((mode) => { if (mode.ModeKey == key) return true; return false; });

            foreach(var mode in upDataList)

            {

                mode.ModeValue = value;

            }

            return upDataList.Count;

        }

    }

 

Global:

默认情况下,模板自带了两个路由规则,分别对应于WebAPI和普通MVC的Web请求,默认的WebAPI路由规则如下

1  routes.MapHttpRoute( 2                 name: "DefaultApi", 3                 routeTemplate: "api/{controller}/{id}", 4                 defaults: new { id = RouteParameter.Optional } 5             );

简单使用JS调用上面提供的数据接口:

 function getAll() {

 2             $.ajax({

 3                 url: "api/Test/",

 4                 type: 'GET',

 5                 success: function (data) {

 6                     document.getElementById("modes").innerHTML = "";

 7                     $.each(data, function (key, val) {

 8                         var str = val.ModeKey + ': ' + val.ModeValue;

 9                         $('<li/>', { html: str }).appendTo($('#modes'));

10                     });

11                 }

12             }).fail(

13             function (xhr, textStatus, err) {

14                 alert('Error: ' + err);

15             });

16         }

17 

18 

19 

20         function add() {

21 

22             $.ajax({

23                 url: "api/Test/",

24                 type: "POST",

25                 dataType: "json",

26                 data: { "ModeKey": document.getElementById("txtKey").value, "ModeValue": document.getElementById("txtValue").value },

27                 success: function (data) {

28                     getAll();

29                 }

30             }).fail(

31             function (xhr, textStatus, err) {

32                 alert('Error: ' + err);

33             });

34 

35         }

36 

37         function find() {

38             

39             $.ajax({

40                 url: "api/Test/" + document.getElementById("txtFindKey").value,

41                 type: 'GET',

42                 success: function (data) {

43                     document.getElementById("modes").innerHTML = "";

44                     $.each(data, function (key, val) {

45                         var str = val.ModeKey + ': ' + val.ModeValue;

46                         $('<li/>', { html: str }).appendTo($('#modes'));

47                     });

48                 }

49             }).fail(

50             function (xhr, textStatus, err) {

51                 alert('Error: ' + err);

52             });

53         }

54 

55         function removeAll() {

56             $.ajax({

57                 url: "api/Test/",

58                 type: 'DELETE',

59                 success: function (data) {

60                     document.getElementById("modes").innerHTML = "";

61                     getAll();

62                 }

63             }).fail(

64             function (xhr, textStatus, err) {

65                 alert('Error: ' + err);

66             });

67         }

68 

69         function remove() {

70             $.ajax({

71                 url: "api/Test/"+document.getElementById("txtRemoveKey").value,

72                 type: 'DELETE',

73                 success: function (data) {

74                     document.getElementById("modes").innerHTML = "";

75                     getAll();

76                 }

77             }).fail(

78             function (xhr, textStatus, err) {

79                 alert('Error: ' + err);

80             });

81         }

82 

83         function update() {

84             $.ajax({

85                 url: "api/Test/",

86                 type: 'PUT',

87                 dataType: "json",

88                 data: { "key": document.getElementById("txtUpdateKey").value, "value": document.getElementById("txtUpdateValue").value },

89                 success: function (data) {

90                     document.getElementById("modes").innerHTML = "";

91                     getAll();

92                 }

93             }).fail(

94             function (xhr, textStatus, err) {

95                 alert('Error: ' + err);

96             });

97         }

这样就实现了最基本的CRUD操作。

目前来看有这几种比较成熟的方法,个人比较喜欢最后一种。

你可能感兴趣的:(实现)