WCF中的管道——管道类型

管道是所有消息进出WCF应用程序的渠道。它的职责是以统一的方式编制和提供消息。管道中定义了传输、协议和消息拦截。管道以层级结构的形式汇总,就创建了一个管道栈。管道栈以分层的方式进行通信并处理消息。例如,一个管道栈可以使用一个TCP协议管道和一个交互协议管道共同组建。这样的一个管道栈就可以允许从客户端岛服务器端,通过网络发送和接收使用TCP协议和交互式协议的消息。

管道栈的目的是将一个消息转化为发送者和接收者之间都兼容的格式来传递消息。有两种类型的管道可以使用:传输管道和协议管道。传输管道始终防止在管道栈的底部,它的责任是使用一个传输协议传递消息。WCF提供了许多传输协议,包括HTTP、TCP、MSMQ、Peer-to-peer以及命名管道。协议管道驻留在传输管道或其他协议管道的顶端。由于协议管道驻留在其他管道的顶端,他们通常称为分层管道。协议管道的职能是通过翻译和修改消息来实现线路级别上的协议。WCF提供许多类型的协议管道。例如包括实现安全支持的、传输支持的以及可靠性支持的协议管道。

提示:传输协议

WCF提供多个传输管道,包括HTTP、TCP、MSMQ、PtoP以及命名管道。其他的传输方式在示例代码中或通过第三方插件也可以使用,这样就实现更广泛的传输,包括SMTP、FTP、UDP、WebSphere MQ,以及SQL Server 代理。这些传输管道大多可以在http://wcf.netfx3.com的网站上找到。UDP传输管道可以在Windows SDK中找到。针对WebSphere MQ可以在IBM的alphaWorks网站上找到。

通信发生时,客户端和服务端需要实例化一个互相匹配的管道栈。在.NET应用程序之间,在客户端和服务端使用同一管道栈是典型的做法。一般来说,他们的功能必须匹配。我们使用绑定来简化管道栈的创建。一个绑定捕获管道栈的配置,并知道如何在运行时创建一个管道栈。绑定构建了一个绑定元素的集合,他们通常代表管道栈中的管道。绑定和绑定元素将会在后面进行讨论。

WCF管道架构允许通过应用程序抽象的沟通,从而提供了极大的灵活性。这就使开发者构建可以暴露给多个通信机制的服务,这就使应用程序服务可以根据需求变化的时间来改变服务。例如,一个WCF服务暴露在两个.NET应用程序之间,而这个服务可以轻易的暴露给Java应用程序而不需要更改应用程序本身。同时它还支持如互操作性、持久化消息,而且传输可以根据需求的变化轻松的附加到WCF服务上。之前的微软的技术(如ASP.NET Web服务、.NET Remoting、企业服务或MSMQ)要求你为每个新的通信形式重写应用程序的操作。而使用WCF,你现在可以选择你想要的通信技术,而不需要大量的重写应用程序。

WCF的功能还针对如何使用层级结构组建一个管道栈而提供非常大的灵活性。如下图所示,一个消息如何从一个WCF客户端应用程序管道栈传递到一个给定的服务端。该服务的管道栈监听消息,然后将这些消息指派到服务端应用。

image_thumb1

一个管道栈是一系列使用绑定元素已配置好的管道。一个预定义的管道栈也叫做一个绑定。一个绑定由一系列的绑定元素构成,就像一个管道栈由一系列的管道组成一样。在这个栈的顶端是一个协议管道。协议管道与一个消息相互作用,而且更有利于安全、可靠的消息、传输和日志等功能。一个管道栈中可能有多个协议管道,他们依赖于不同的功能需求。

传输管道负责通过一个转换协议,如TCP或HTTP,发送字节信息。他们也负责使用一个编码形式来将一个消息转化为字节数组以便于传输。这种编码形式的职能是把消息从它本身的XML表现形式转化为字节数组的形式。编码器使用绑定元素暴露给传输管道。传输通道通过MessageEncoder类查看绑定内容。如果没有匹配项,传输管到会定义一个默认的消息编码器。

提示:管道栈有一个传输器和一个编码器

管道栈有至少一个传输器和一个编码器。通常传输器将定义一个默认的编码器来使用。例如tcpTransport传输管道指定使用binaryMessageEncoding。这些都是WCF中实现一个管道栈所必须的。协议管道在编辑管道栈时是可选的。

管道类型

WCF支持三种不同的消息交换模式:单项、全双工和请求。为了方便每种模式,WCF提供了10种不同的接口,叫做管到类型。其中的5个是IOutputChannel、IInputChannel、IDuplexChannel、IRequestChannel以及IReplyChannel。这些类型对于支持会话状态来说都是对等的。他们包括IOutputSessionChannel、IInputSessionChannel、IDuplexSessionChannel、IRequestSessionChannel以及IReplySessionChannel。这些接口在管道栈中实现不同的消息交换模式。在这里我们会看到每种通信模式和各种接口的关系。

单向通信模式

单向通信模式中,消息只在一个方向上发送,就是从客户端到服务端。当发送者并不需要一个信息马上回应时,通常应用单向通信;此时发送者只需要一个消息已被发送的确认。消息发送后,通信就结束。用于实现单向通信的两个接口是IOutputChannel以及IInputChannel接口。下图显示了,单向通信中,消息是如何在客户端和服务端流动的。在这个模式中,IOutputChannel接口负责发送消息,而IInputChannel负责接收消息。下面代码显示了一个客户端程序使用IOutputChannel管道来发送消息。image_thumb1[1]

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;namespace WCFOneWayChannelClient
{class Program{static void Main(string[] args){BasicHttpBinding binding = new BasicHttpBinding();BindingParameterCollection parameters = new BindingParameterCollection();Message m = Message.CreateMessage(MessageVersion.Soap11,"urn:sendmessage");IChannelFactory<IOutputChannel> factory = binding.BuildChannelFactory<IOutputChannel>(parameters);IOutputChannel channel = factory.CreateChannel(new EndpointAddress("http://localhost/sendmessage"));channel.Send(m);channel.Close();factory.Close();}}
}

全双工通信

双工通信使用两个单向管道,组合成第三个接口叫做IDuplexChannel,如下图所示。双工通信与单向或请求响应模式相比,优点在于消息可以在客户端和服务端之间互相发送。image_thumb3

全双工通信的一个例子是一个事件通知系统。一个服务端将会发送事件到客户端,客户端接收事件。客户端提供一个端点,以便服务端可以通过这个端点将消息发送到客户端。然后服务端使用端点来发送消息到客户端。下面代码显示了一个例子,一个客户端使用IDuplexChannel管道类型。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;namespace WCFDuplexChannelClient
{class Program{static void Main(string[] args){NetTcpBinding binding = new NetTcpBinding();BindingParameterCollection parameters = new BindingParameterCollection();Message m = Message.CreateMessage(MessageVersion.Soap12WSAddressing10,"uru:sendmessage");IChannelFactory<IDuplexChannel> factory = binding.BuildChannelFactory<IDuplexChannel>(parameters);IDuplexChannel channel = factory.CreateChannel(new EndpointAddress("net.tcp://localhost/sendmessage/"));channel.Send(m);channel.Close();factory.Close();}}
}

请求响应通信

请求响应通信是一种特殊的双向通信,其中每个请求都有明确的响应,而且它总是由客户端发起。客户端发送了请求后,它就必须等待响应,然后才可以发送另一个请求。请求响应通信的通常用法是,从一个浏览器发送的一个HTTP请求。浏览器生成一个HTTP请求到服务端,如GET或POST,服务端处理请求,然后一个响应被回发。WCF使用IRequestChannel和IReplyChannel接口处理请求响应通行。如下图所示:image_thumb5

下面代码显示了一个客户端应用程序使用IRequestChannel来发送一个消息。注意,Request方法以返回值参数来返回响应消息。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;namespace WCFRequestReplyChannelClient
{class Program{static void Main(string[] args){BasicHttpBinding binding = new BasicHttpBinding();BindingParameterCollection parameters = new BindingParameterCollection();Message request = Message.CreateMessage(MessageVersion.Soap11,"urn:sendmessage");IChannelFactory<IRequestChannel> factory = binding.BuildChannelFactory<IRequestChannel>(parameters);IRequestChannel channel = factory.CreateChannel(new EndpointAddress("http://localhost/sendmessage/"));Message response = channel.Request(request);channel.Close();factory.Close();}}
}

类型变更

内置的HTTP协议内在具有请求响应的性质,因此HTTP传输管道使用请求响应管道类型。其它的通信模式,如单向和双工,通过HTTP完成类型变更。通过分层协议管道顶端的传输管道,以支持单向或双工通信。下面的代码显示一个自定义的绑定,来分层一个单项类型管道绑定元素,OneWayBindingElement,在HTTP传输的顶端。后面的部分中,我们会看到使用CompositeDuplexBindingElement绑定元素实现类型变更的更优化的案例。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;namespace WCFShapeChangingClient
{class Program{static void Main(string[] args){CustomBinding binding = new CustomBinding(new OneWayBindingElement(),new TextMessageEncodingBindingElement(),new HttpTransportBindingElement());}}
}

操作契约和管道类型

管道使用管道类型来实现对多种消息交换模式的支持。例如,一个基于TCP的传输管道将实现IInputChannel和IOutputChannel,因为这些传输本质上是单向模式。基于其它传输的其它协议,如TCP,可以实现多个管道类型。开发人员并不直接操作管道的类型。相反,WCF会基于一个服务的操作契约选择管道的类型。下面表格列出了你可以在操作契约中设置的各种属性以及结果管道类型。注意,大多数管道类型具有无会话状态和会话状态感知两种变化。会话感知管道从客户端向服务端传递一个标识符。这就可以在服务端和客户端之间维护会话状态。这类似于ASP.NET中的状态管理。WCF中没有状态管理功能,但是你可以使用会话状态与实例来管理状态。实例管理会在后面介绍。

image_thumb7

不是所有的管道都实现了每个接口。如果基础管道不支持某个特定的管道类型,WCF将尝试适配一个存在的管道类型以满足需要。例如,如果一个单向管道没有实现IInputChannel和IOutputChannel接口,,WCF将会尝试使用IDuplexChannel或IRequestChannel/IReplyChannel实例。

管道监听

管道监听器构成了WCF中基本的服务端通信。他们负责监听进入的消息,创建管道栈以及提供指向应用程序栈顶的引用。他们从传输管道或从管道栈中的管道中接收消息。大多数开发人员不会直接操作监听器。他们使用ServiceHost类来宿主那些使用管道监听器监听消息的服务。我们会在介绍宿主时详细介绍ServiceHost类。下面代码显示了一个管道监听器被创建用来接收消息。绑定的BuildChannelListener方法基于特定类型的管道构建一个管道监听器。这个例子中,我们使用BasicHttpBinding和IReplyChannel类型。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Runtime.Serialization;namespace WCFChannelListenersServer
{class Program{static void Main(string[] args){BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);Uri address = new Uri("http://localhost/request");BindingParameterCollection bpc = new BindingParameterCollection();Console.WriteLine("Starting service...");IChannelListener<IReplyChannel> listener = binding.BuildChannelListener<IReplyChannel>(address, bpc);listener.Open();IReplyChannel channel = listener.AcceptChannel();channel.Open();Console.WriteLine("Service started!");Console.WriteLine("Waiting for request...");RequestContext request = channel.ReceiveRequest();Message message = request.RequestMessage;string data = message.GetBody<string>();Message replymessage = Message.CreateMessage(message.Version,"http://localhost/reply",data);request.Reply(replymessage);Console.WriteLine("Service stopped!");message.Close();request.Close();channel.Close();listener.Close();Console.ReadLine();}}
}

管道工厂

管道工厂创建一个管道来发送消息并维护它创建的管道所有权。大多数开发者从不会直接使用管道工厂。相反,他们会使用一个类,继承自ClientBase<>,这个类通常由svcutil.exe或添加服务引用操作生成。然而,重要的是要了解管道工厂,因为他们构成WCF客户端通信的基础。

提示,管道工厂拥有它们的管道。管道监听器和工厂之间最重要的区别是管道工厂负责关闭所有相关联的管道;管道监听器不是。这种区别使管道监听器可以独立的关闭他们依赖的管道。

下面代码显示了使用一个管道工厂来调用服务。这是在上面例子中服务的客户端。这段代码使用绑定的CreateChannel方法来创建一个新的管道。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Runtime.Serialization;namespace WCFChannelFactoryClient
{class Program{static void Main(string[] args){BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);IChannelFactory<IRequestChannel> factory = binding.BuildChannelFactory<IRequestChannel>(new BindingParameterCollection());factory.Open();IRequestChannel channel = factory.CreateChannel(new EndpointAddress("http://localhost/request"));channel.Open();Message requestMessage = Message.CreateMessage(MessageVersion.Soap11,"http://chinasofti.com/reply","This.is the body data");Console.WriteLine("Sending message...");Message replymessage = channel.Request(requestMessage);string data = replymessage.GetBody<string>();Console.WriteLine("Reply received!");requestMessage.Close();replymessage.Close();channel.Close();factory.Close();Console.ReadLine();}}
}

ChannelFactory<>

WCF中的两个类代表管道工厂:ChannelFactory和ChannelFactory<>。他们可能看起来比较相似,但是实际上他们做不同的事情。ChannelFactory<>类用在高级的情况下,如多个客户段需要创建时。本质上它与一个给定的ChannelFactory一起工作,但是它不负责创建管道栈。ChannelFactory<>类用来使用一个特定的服务契约类型定义一个类。下面代码显示一个案例,其中一个使用ChannelFactory<>类调用一个实现了IStockQuoteService接口的服务端。

提示,使用状态机制和ChannelFactory<>。使用状态机制关闭ChannelFactory时要小心。下面代码显示了在服务调用代码的外围使用try…catch以便从服务端抛出的错误都能被捕获。如果我们不使用try…catch,任何异常都有可能在使用过程中冒出来。从这点上来说,管道工厂应该在它关闭后抛出异常。这有可能使之前的错误从服务调用中暴露出来。我们使用两个try…catch块,使我们可以从服务调用中抓住任何异常。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;namespace WCFChannelFactoryClassClient
{class Program{static void Main(string[] args){try{using (ChannelFactory<IStockQuoteService> cf = new ChannelFactory<IStockQuoteService>()){IStockQuoteService service = cf.CreateChannel();try{double value = service.GetQuotr("ChinaSofti");}catch (Exception ex){//check exception from call to GetQuoteConsole.WriteLine(ex.ToString());}}}catch (Exception ex){//check exception for creating channelConsole.WriteLine(ex.ToString());}Console.ReadLine();}}
}

ICommunicationObject

WCF中,ICommunicationObject接口是所有通信对象的基础(管道、管道工厂、管道监听等等)。开发人员要想定义自定义管道或者直接操作管道时,就需要了解这个接口。WCF中的通信对象需要实现一个特殊的状态机。这个状态机表现了所有通信对象运行的状态。这种方法类似于其它对象(如sockets).ICommunicationObject接口的目的是实现状态机。这允许WCF对所有通信对象形同看待,并抽象他们的基本实现。image_thumb9

下面代码显示了状态机制中提供的通信状态枚举。

public enum CommunicationState
{Created, Opening, Opened, Closing, Closed, Faulted
}

CommunicationState枚举列出了通信对象的六个状态。所有通信对象的初始状态是Created。当通信对象被实例化时,这个状态表明该通信对象进入系统。所有通信对象的最终状态是Closed。沿着这个方式,ICommunicationObject接口上的方法被一一调用,从而将通信对象从一个状态转换到另一个状态。例如,Open方法被调用,通信对象的状态从Created状态转换到了Opened状态。下图展示了一个状态图以表明通信对象在状态与状态之间的变化。image_thumb11

通信对象的一个例子就是ClientBase<>类,这个类是从添加服务引用操作或svcutil.exe生成客户端代码时的基本实现类。

注意,不能重复使用客户端。当一个通信对象已经从Opened状态转换到Closing或Faulted状态后,就不能回滚。这就意味着,通信对象不能返回Opened状态,除非首先重复创建这个通信对象。因此,客户端需要在他们被关闭后,重新创建。

五个事件(Opening,Opened,Closing,Closed和Faulted)是ICommunicationObject支持的方法。这些事件用来标示代码状态的转换。

提示,客户端通知。通常情况下应用程序会维护一个客户端代理的引用。这种情况下,使用状态转换事件,当客户端代理进入Faulted状态时用作通知(并最终转换到Closed状态)使客户端和服务端之间的通信能够维持下去。

ICommunicationObject接口通常用来将一个现有通信对向转换为接口类型,以获得访问ICommunicationObject中暴露的方法和事件。然而,其它时候,你想要创建一个新的通信对象来扩展WCF的能力。在这种情况下,WCF提供一个抽象基类调用CommunicationObject,它提供了ICommunicationObject接口的实现以及状态机制的关联。下面代码显示一个由svcutil.exe生成的StockQuoteServiceClient。这个客户端继承自ClientBase<>类。代码显示这个客户端被转化为ICommunicationObject接口,以便我们可以访问通信事件。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;namespace WCFICommunicationObjectClient
{class Program{static void Main(string[] args){string symbol = "ChinaSofti";double value;StockQuoteServiceClient client = new StockQuoteServiceClient();ICommunicationObject commobj = (ICommunicationObject)client;commobj.Closed += new EventHandler(commobj_Closed);commobj.Faulted += new EventHandler(commobj_Faulted);value = client.GetQuote(symbol);Console.WriteLine("{0} @ $ {1}",symbol,value);Console.ReadLine();}static void commobj_Faulted(object sender, EventArgs e){//Handle Closed Event}static void commobj_Closed(object sender, EventArgs e){//Handle Faulted Event}}
}

转载于:https://www.cnblogs.com/zhangdong/archive/2010/01/13/1646484.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/496086.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android德州扑克计算器,学界 | 一台笔记本打败超算:CMU冷扑大师团队提出全新德扑AI Modicum...

原标题&#xff1a;学界 | 一台笔记本打败超算&#xff1a;CMU冷扑大师团队提出全新德扑AI Modicum选自arXiv参与&#xff1a;路、晓坤CMU 冷扑大师团队在读博士 Noam Brown、Tuomas Sandholm 教授和研究助理 Brandon Amos 近日提交了一个新研究&#xff1a;德州扑克人工智能 M…

神器 | 百度云资源搜索

From&#xff1a;https://blog.csdn.net/qq_21492635/article/details/81109247 直接上神器 该网页没有做自适应&#xff0c;也没有专门的手机站点&#xff0c;因此建议电脑使用。也可下载桌面客户端&#xff08;仅支持windows&#xff09;&#xff0c;稳定不卡&#xff0c;速度…

html前端如何缓存页面,Nuxt中如何做页面html缓存

Nuxt是一款基于Vue的服务端渲染SSR框架在Nuxt框架的API中&#xff0c;有一个叫 serverMiddleware 的服务端中间件&#xff0c;我们可以利用它在返回首屏html前做一些缓存的处理在这之前我们需要了解一个叫LRU的算法&#xff0c;LRU是一种缓存淘汰算法&#xff0c;用链表存储数据…

Google 和 bing 都无法替代的10大深网搜索引擎

From&#xff1a;https://blog.csdn.net/ejinxian/article/details/74081716 当我们想要搜索某些内容时&#xff0c;我们第一个想到的就是打开Google、百度或必应这类的搜索引擎。但针对有些内容&#xff0c;却是这些常规搜索引擎无法获取到的&#xff0c;那就是隐藏在深网的内…

植树节html5游戏,植树节活动

活动概述活动时间:3月10日至3月13日(以实际版本内活动日期为准)活动介绍:一年一度的植树节活动开始了&#xff0c;小伙伴们拿起小铲子&#xff0c;小水桶&#xff0c;今天勤劳来种树&#xff0c;明天不用吸雾霾&#xff01;快来邀请你的小伙伴一同参与活动吧&#xff0c;开开心…

Swagger 注解~用于Controller

Api 用于类&#xff1b;表示标识这个类是swagger的资源 tags–表示说明 value–也是说明&#xff0c;可以使用tags替代但是tags如果有多个值&#xff0c;会生成多个list Api(value"用户controller",tags{"用户操作接口"}) RestController public class Us…

大黄蜂(HORNET):比Tor更快更安全的匿名网络

From&#xff1a;https://blog.csdn.net/lee_sire/article/details/50357234 你一定听说过Tor洋葱路由技术&#xff0c;它提供了强大的匿名网络访问功能&#xff0c;以此成为互联网用户、政治活动家、以及记者躲避有关部门限制监控的方法。但Tor最受人诟病的是它蜗牛般的网络连…

HTML在前端开发中起到的作用,什么是字符串,web前端开发里起到什么作用

观察某宝商品数据&#xff0c;有一个东西叫服务器>>>>js的作用重要作用之一>>>>交互>>>>人机交互(事件)>>>>服务器交互(ajax);服务器交互&#xff0c;数据处理方式json>>>>>要把它转化成字符串操作。字符串操作…

Swagger 注解~用于方法

ApiOperation 用于方法&#xff1b;表示一个http请求的操作 value用于方法描述 notes用于提示内容 tags可以重新分组&#xff08;视情况而用&#xff09;ApiParam 用于参数&#xff0c;字段说明&#xff1b;表示对参数的添加元数据&#xff08;说明或是否必填等&#xff09; na…

如何使用Linux匿名上网-四大法宝

From&#xff1a;https://www.linuxprobe.com/linux-anonymity-internet.html 导读 信息时代给我们的生活带来极大便利和好处的同时也带来了很大的风险。一方面&#xff0c;人们只要点击几下按钮&#xff0c;就能基本上访问已知存在的全部信息和知识;另一方面&#xff0c;要是这…

怎么改HTML表单数据,form设置的数据怎么添加到table

如图&#xff1a; 是一个form表单&#xff0c;在顶部输入数据点击新增&#xff0c;怎么把数据插入到下面的表格中&#xff0c;并显示。页面代码&#xff1a;编辑跳转表单的代码&#xff1a;showEditForm(text) >{const data_save this.props.signal.data_save.dataconst da…

Swagger 注解~用于模型

ApiModel 用于模型类 &#xff1b;表示对类进行说明&#xff0c;用于参数用实体类接收 value–表示对象名 description–描述 都可省略ApiModelProperty 用于字段&#xff1b; 表示对model属性的说明或者数据操作更改 value–字段说明 name–重写属性名字 dataType–重写属性类…

命令行下 pdb 调试 Python 程序

官方参考网站 The Python Debugger &#xff1a; https://docs.python.org/3/library/pdb.html gdb 调试命令的使用及总结&#xff1a;https://blog.csdn.net/freeking101/article/details/54406982 使用 Pdb 调试 Python&#xff1a;https://segmentfault.com/a/1190000006628…

2021年高考成绩查询山东德洲,2021年德州高考状元是谁分数多少分,历年德州高考状元名单...

2020年德州一年一度的高考考试已经结束&#xff0c;今年德州高考状元是谁呢&#xff0c;德州高考状元出自哪个高中学校&#xff0c;文理科分数是多少分&#xff0c;一起来了解。一、2020年德州高考状元名单资料2020年德州高考状元名单和学校相关信息&#xff0c;截至目前发文时…

Swagger 注解~其他

ApiIgnore 用于类或者方法上&#xff0c;可以不被swagger显示在页面上 比较简单, 这里不做举例 ApiImplicitParam 用于方法&#xff0c;表示单独的请求参数ApiImplicitParams 用于方法&#xff0c;包含多个 ApiImplicitParam name–参数ming value–参数说明 dataType–数据类…

python3 爬虫实战 :用 Appium 抓取手机 app 微信朋友圈的数据

From&#xff1a;https://blog.csdn.net/Fan_shui/article/details/81413595 本编教程从 appium 的环境配置开始&#xff0c;到抓取手机 app 微信朋友圈结束。 知乎&#xff1a;https://zhuanlan.zhihu.com/p/41311503 GitHub&#xff1a;https://github.com/FanShuixing/git_…

SharePoint 2010中的内容类型集线器 - 内容类型发布与订阅

原文地址&#xff1a;http://www.chakkaradeep.com/post/SharePoint-2010-Content-Type-Hubs-e28093-Publish-and-Subscribe-to-Content-Types.aspx 注&#xff1a;此博客帖子是基于SharePoint2010技术预览版本。 MOSS 2007 假设您有一个网站集Web Application1 &#xff0c;在…

如何用“底层逻辑”,看清世界的底牌?

来源&#xff1a;如何用“底层逻辑”&#xff0c;看清世界的底牌&#xff1f; 我的新书《底层逻辑》&#xff0c;终于要和大家见面了。 我常说&#xff0c;只有底层逻辑才有生命力。 因为底层逻辑在面临变化的时候&#xff0c;能够应用到新的变化里面&#xff0c;会产生出新…

python3 爬虫实战:mitmproxy 对接 python 下载抖音小视频

From&#xff1a;https://blog.csdn.net/Fan_shui/article/details/81461253 一、前言 前面我们已经用 appium 爬取了微信朋友圈&#xff0c;今天我们学习下 mitmproxy&#xff0c;mitmproxy 是干什么的呢&#xff0c;它跟 charles 和 fiddler类似&#xff0c;是一个抓包工具&a…