asp.net中回发是怎么回事?高手解答下,越详细越好,言简意赅容易明白的亦可,谢啦

asp.net中回发是怎么回事?高手解答下,越详细越好,言简意赅容易明白的亦可,谢啦,第1张

相信很多开发过AJAX的朋友都遇到过回发和回调的问题,今天我们就撇开AJAX来单独谈一谈回发,并通过一组简单的示例进行释疑。我们先在页面上添加一个客户端链接控件,设置其Id为“aLink”,看起来应该像这样:

 1:<a id="aLink" onclick="__doPostBack('aLink','[aLink_EventArg]')>aLink</a> 

保存并在浏览器中查看,点击链接后系统会提示脚本错误,原因很简单,查看页面源代码就知道,当前不存在__doPostBack这个回发函数,这就与调用了一个不存在的Javascript函数一样。

 

先把这个问题放在一边,接下来我们在页面上添加一个服务器端按钮控件,设置其Id为“btn1”,并将其onClientClick属性设置为一个回发函数,看起来应该像这样:

 1:<asp:Button ID="btn1" runat="server" Text="Btn1" OnClientClick="__doPostBack('btn1','[btn1_EventArg]')" /> 

保存并在浏览器中查看,点击以后出现和刚才一样的脚本错误,原因之前已经说了,同时说明NET Framework不会为服务器端控件自动生成回发函数。

 

我们把这个问题也放在一边,接下来再在页面上添加一个服务器端按钮控件,这次在前端不需要设置额外的属性,所以它看起来应该像这样:

 1:<asp:Button ID="btn2" runat="server" Text="Btn2" /> 

这还没完,我们需要切换到代码视图,并重写Page的呈现方法,看起来应该像这样:

 1:protected override void Render(HtmlTextWriter writer) {2:    thisbtn2OnClientClick += ClientScriptGetPostBackEventReference(thisbtn2, "[btn2_EventArg]", true);3:    baseRender(writer);4:} 

GetPostBackEventReference方法的作用是返回一段用于客户端事件的字符串,以触发到服务器端的回发。接收的第一个参数是用来处理回发的控件,第二个是用来处理额外事件信息的字符串形式参数,第三个是是否注册事件引用以进行验证。跟踪这个方法所返回的字符串就会发现,它与我们为Btn1所写的回发字符串别无二致。保存这些修改并在浏览器中查看,我们惊喜地发现Btn2可以正常工作(尽管光从页面源代码比较Btn1和Btn2无法看出有什么区别),更加令人惊喜的是,假如你在IE下进行调试(笔者的IE版本为IE8),那么会发现连之前不能工作的两个控件也运行地很好。其实原因是因为GetPostBackEventReference不仅仅返回一段用来触发回发的字符串,而且在服务器端注册了回发事件,在页面的源代码中我们可以看到系统自动生成了__doPostBack函数。但如果你还装有其它的浏览器(Chrome或是Firefox),那么用它们来打开页面,你就会发现点击Btn1将会使NET Framework抛出一个异常,具体内容如下:

 

NET Framework出于安全考虑需要为服务器端控件的回发和回调事件进行注册,因为Btn1没有进行过类似注册(Btn2使用GetPostBackEventReference进行了注册),所以会抛出异常,这也正是aLink不会引起异常的原因(因为它是客户端控件)。你可以手动关闭对回发和回调的验证,方法是将Page或是Webconfig中的EnableEventValidation属性设置为False(如果两者设置有冲突,以Page的为准),看起来应该像这样:

 1:<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ClientPostbackaspxcs" Inherits="WebApplication1ClientPostback"  EnableEventValidation="false" %> 

或是:

 1:<systemweb>2:    <pages enableEventValidation ="false"></pages>3:</systemweb> 

但是这种无视安全性的做法是不值得推荐的,除非回发或回调的事件是不可预测的,否则应该为每一个回发或回调事件进行注册。要想为Btn1进行注册,需要回到代码视图,在之前的页面呈现方法中添加注册(注册这一行为只能写在PageRender中,同时需要注意注册的控件唯一标识和参数必须与前端保持一致),修改后的Render看起来应该像这样:

 1:protected override void Render(HtmlTextWriter writer) {2:    PageClientScriptRegisterForEventValidation(thisbtn1UniqueID,"[btn1_EventArg]");3:    thisbtn2OnClientClick += ClientScriptGetPostBackEventReference(thisbtn2, "[btn2_EventArg]", true);4:    baseRender(writer);5:} 

现在即使我们在非IE浏览器下触发回发事件也能够正常运行了。目前Btn1和Btn2所包含的代码可以说是等价的,但要想进行回发还有更加简便的方法。

 

再在页面中添加一个服务器端按钮控件,将其Id设置为“btn3”,并将它的UseSubmitBehavior属性设置为False,看起来应该像这样:

 1:<asp:Button ID="btn3" runat="server" Text="Btn3" UseSubmitBehavior="False" onclick="btn3_Click" /> 

UseSubmitBehavior的默认属性是True,这意味着点击按钮默认将会触发浏览器的提交操作,而设置成False意味着点击按钮将会触发NET Framework的回发操作,请注意触发源和触发行为的不同。设置了UseSubmitBehavior属性以后系统将会自动为其进行注册,注册使用的控件唯一标识是控件的UniqueID,参数为空字符串。

 

接下来我们再在页面中添加一个服务器端按钮,将其Id设置为“btn4”(好吧,我承认用数字进行排序的Id过不了多久就会让人产生迷茫,不过作为一个小例子,我想把更多的精力放在叙述的流畅度上而不是绞尽脑汁为它们起一个优雅的名字),并将其onClientClick设置为“__doPostBack('btn3','')”,看起来应该像这样:

 1:<asp:Button ID="btn4" runat="server" Text="Btn4" OnClientClick="__doPostBack('btn3','')" /> 

保存并在浏览器中查看,点击Btn4会发现,虽然我们没有进行注册,但是它运行地很好,这说明回发事件的注册与服务器控件本身的ID无关,只要保证回发事件中的UniqueID被注册过(Btn3被系统自动注册,前面已经说到过),就能成功进行调用。

 

如果你在btn3_Click中对sender进行捕捉并且足够细心,你就会发现回发和提交的最大不同:如果通过提交进入,那么sender将是触发提交的那个按钮;如果通过回发进入,那么sender将是ID与回发函数中的UniqueID对应的那个按钮。也就是说,在Click方法中,后端无法知道到底是谁真正触发了它,因为你跨过了浏览器,直接向服务器端发送了请求

常见的网络安全事件攻击主要类型有:

1、DDoS攻击

DDoS是最常见的一种攻击方式,攻击者通过向某一个站点服务器反复发送请求,导致服务器无法承载大量的请求而产生“拒绝服务”,这就导致正常的服务无法进行,影响我们服务器的使用。

2、获取账号和密码

这类攻击会存在一定的技术性。一般来说,攻击者会利用程序来抓取数据包,获取口令和数据内容,通过侦听程序在来监视网络数据流,进而通过分析获取用户的登录账号和密码。

3、SQL注入

SQL注入的攻击手段主要是利用后台的漏洞,通过URL将关键SQL语句带入程序,在数据库中进行破坏。许多的攻击者会使用F12或者postman等拼装ajax请求,将非法的数字发送给后台,造成程序的报错,并展现在页面上,这样攻击者就会知道后台使用的语言和框架了。

4、恶意小程序

这类攻击的方式主要存在我们使用的程序上面,它们可以通过入侵修改硬盘上的文件、窃取口令等。

5、木马植入

这种攻击方式主要是通过向服务器植入木马,开启后面,获取服务器的控制权,恶意破坏服务器文件或**服务器数据,这类的危害都是比较大的。

网络攻击的4个类型如下:

1、侦察。侦察是指未经授权的搜索和映射系统、服务或漏洞。此类攻击也称为信息收集,大多数情况下它充当其它类型攻击的先导。侦察类似于冒充邻居的小偷伺机寻找容易下手的住宅,例如无人居住的住宅、容易打开的门或窗户等。

2、访问。系统访问是指入侵者获取本来不具备访问权限(帐户或密码)的设备的访问权。入侵者进入或访问系统后往往会运行某种黑客程序、脚本或工具,以利用目标系统或应用程序的已知漏洞展开攻击。

3、拒绝服务。拒绝服务 (dos) 是指攻击者通过禁用或破坏网络、系统或服务来拒绝为特定用户提供服务的一种攻击方式。dos 攻击包括使系统崩溃或将系统性能降低至无法使用的状态。但是,dos 也可以只是简单地删除或破坏信息。

大多数情况下,执行此类攻击只需简单地运行黑客程序或脚本。因此,dos 攻击成为最令人惧怕的攻击方式。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中, 浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每 1 秒),由浏览器对服务器发出 HTTP 请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而 HTTP 请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后, 客户端和服务器端就可以通过 TCP 连接直接交换数据

当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息"Upgrade: WebSocket"表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接

socketio 是一个类库,内部封装了 WebSocket,可以在浏览器与服务器之间建立实时通信。

如果某些旧版本的浏览器不支持 WebSocket,socketio 会使用轮询代替。另外它还具有可发送二进制消息、多路复用、创建房间等特性,因此相比直接使用原生 WebSocket,socketio 是更好的选择。

开发一个实时应用主要分两部分:服务端和客户端,socketio 分别提供了相应的 npm 包供我们方便地调用。

接下来就通过一个生动形象且有趣的栗子分别介绍这两大块。

现在假设李白张三,李四,王五 5 个人加入了一个叫 棋牌室 的房间,在文章结束时我们将拥有一个麻雀虽小五脏俱全的峡谷英雄在线聊天室。

客户端的功能到这基本上也开发完了。核心 api 就是 on 和 emit 用于收发消息,既简单又优雅。

本文在官方介绍基础上简化总结而成

CZML 可以理解为 Cesium Language 的简写,是cesium中很重要的一个概念,使得cesium很酷很炫地展示动态数据成为可能

某种程度上说, Cesium 和 CZML的关系就像 Google Earth 和 KML。

一段示例:

在上面的示例中,我们指定了“ GroundControlStation”对象在WGS 84经度-755度,纬度400度和高度00米处具有固定的位置,并在其位置绘制了一个蓝色的Point。

每个数据包都有一个id属性,用于标识正在描述的对象。 ID不必是GUID,但它们确实需要唯一地标识CZML源中的单个对象以及加载到同一作用域中的任何其他CZML源。

如果未指定ID,客户端将自动生成一个唯一的ID。但是,这会阻止以后的数据包引用该对象,以便例如向该对象添加更多数据。

定义某个属性在不同时间间隔内的值时,将该属性定义为一个数组,并用 interval 属性定义在不同时间段的值。

这个示例中,在两个时间间隔内定义someProperty属性,

第一个时间间隔是中午12:00到1:00 PM(属性值是5),

第二个时间间隔是1:00 PM到2:00 PM UTC(属性值是6),

跨越两个间隔之间的边界时,该值将立即更改。我们使用数字来表示值,因为这是一个数字类型的属性。一些属性(尤其是表示位置的属性)允许以多种格式指定值,例如笛卡尔X,Y,Z位置或制图经度,纬度,高度位置。每种类型的页面列出了每种属性支持的数据类型,以及每种属性所使用的值名称。

interval属性是可选的。如果未指定,则假定该间隔跨越所有时间。指定多个无限间隔或通常重叠的间隔没有多大意义,但是如果您指定了此间隔,则在CZML文件或流中的后面一个优先。

如果属性的值在一个长间隔上不变,则只需定义一个,间隔数组可以省略。

如果所有时间内,值都不变,则可简写为:

该缩写表示法对于其值可以用一种简单的JSON数据类型(字符串,数字或布尔值)表示的任何属性均有效。

用JSON数组来表示更复杂的复合值,例如笛卡尔位置或颜色。

对于笛卡尔位置,数组具有三个元素,分别对应于该位置的X,Y和Z分量。

除了上面介绍的可以定义不同时间间隔的单一值和复合值,还可以定义不同时间点的采样值,客户端会根据这些值进行插值计算,补上没有赋值的时间的数据。

注意时间使用ISO 8601字符串指定。

这个示例定义了三个时间点的坐标,则后续时间的值会根据这三个值线性插值计算得出。

这个也可以简写,定义一个开始时间,数据默认以整秒递增,例如:

另外,可以用其他属性控制插值方式

interpolationAlgorithm 属性可选值: "LINEAR", "LAGRANGE", and "HERMITE"

interpolationDegree 属性可选值:1表示线性差值,2表示二次插值法

将整个CZML文档放在一个大JSON数组中,将很难以增量方式加载该文档。 当今的网络浏览器允许在流完成之前对流进行一些访问,但是解析和解释不完整的数据需要缓慢而麻烦的字符串操作。 为了促进高性能流传输,还可以使用现代浏览器的服务器发送事件(EventSource)API来流传输CZML。 使用此API时,每个CZML数据包都作为单独的事件流传输到客户端:

当浏览器接收到一个packet后就会发出一个事件,事件中会包含刚刚接收到了数据。这样我们就可以通过增量的方式高效的处理CZML数据。

目前为止,我们都是使用一个packet包来描述一个对象,这个packet包含了所有这个对象的图形属性。我们还可以使用其他的方式,例如一个CZML文件或流可以包含多个packet,每个packet都有相同的id,分别描述同一个对象的不同方面的属性。

事实上在大多数情况下我们使用两个packet来描述一个对象。当对象属性跨越多个时间间隔,或者一个时间间隔有很多个时间戳采样时,这样做就很有用了。通过将一个属性定义打包进多个packet,我们可以使数据更快的传输到Cesium中,减少用户等待的时间。

当客户端接收到一个packet,它会遍历packet中的每一个属性。对于每个属性,它会遍历属性定义的每个时间间隔。对于每个时间间隔,它会判断这个时间间隔是否已经定义,假如这个间隔已经定义,将更新已经存在的间隔,如果没有定义,那么就根据这个间隔创建一个新的。

当更新一个已存在的时间间隔时,假如有子属性,那么子属性将覆盖原有的值。有一个例外,就是当已有的属性和新接收到的属性都包含时间戳采样时,新接收到的采样不会覆盖已有的,而是加到已有的采样列表中。

当新的时间间隔与已有的发生重叠时,新的间隔拥有较高优先级,原有的间隔将被截断或者整个移除。这点必须要牢记。

在同一个packet中的时间间隔的时间必须以增序排列,不同packet之间就没有要求。但是对于不连续的采样还是应该考虑合理的插值顺序。

如果定义的两个时间段之间时间没有连接上,比如1-3,7-9,中间4-6时间的数据是插值还是空着呢?就用到 previousTime 和 nextTime 属性了

Availability属性指示对象的数据何时可用。如果已知某个对象的数据在当前动画时间可用,但是客户端尚未获得该数据(大概是因为它将在以后的数据包中到达),则客户端可以暂停并显示诸如“正在缓冲等待接收数据。该属性可以是指定单个间隔的单个字符串,也可以是表示间隔的字符串数组。

假如availability变化了或者被发现是不正确的,那么随后的packet将会更新它的值。例如,一个SGP4 propagator可能总是可用的,但是随后他发出了一个异常,所以他的值需要调整。如果availability属性没有定义,那么默认是全部时间内都可用的。Availability的范围被限定到一个特定的CZML流中,所以对同一个对象在两个不同的流中可以有不同的availability。在一个流中,只有定义在最后的那个availability起作用,其他的都会被忽略。在某一时刻,如果一个对象是可用的,那么这个对象至少要有一个可用的属性并且在此时间段内需要的属性都要有定义(也就是获取到了数据),不然Cesium就会等待数据直到接收到数据为止。

可以给CZML增加自定义属性,但是为避免冲突,我们强烈建议你给你的自定义属性加上你特有的前缀。

我的是Delphi 6,不知Delphi 7中的netchart示例中用的是什么通信组件?如果是ServerSocket与ClientSocket,则看一看下面的程序:

在Delphi中,用ServerSocket与ClientSocket组件,建立TCP/IP通信非常容易。

1、创建2个应用程序,一个是Server,另一个是Client。

2、Server程序的窗体上放置ServerSocket组件,并设置其port属性(如:设置为5000),并将Active属性设置为True;

3、Client程序的窗体上放置ClientSocket组件,也设置其port属性,与ServerSocket组件的port属性相同,也设置为5000;设置Adress属性为Server程序所在的机器的IP地址。如果Server程序与Client程序在同一台机器上,则设置Address 为127001 。

再放一个命令按钮,在OnClick事件中添加一行事件处理程序:

ClientSocket1Open;

在OnConnect事件中添加事件处理程序:

procedure TForm1ClientSocket1Connect(Sender: TObject;

Socket: TCustomWinSocket);

begin

memo1linesadd('已经建立连接');

end;

4、Server端:利用ServerSocket1socketconnections[i]sendtext('')

发送文本。在OnClientRead事件中接收Client端发送来的信息:

procedure TForm1ServerSocket1ClientRead(Sender: TObject;

Socket: TCustomWinSocket);

begin

memo1linesadd(socketReceiveText);

end;

5、Client端:利用ClientSocket1SocketSendText('')

发送文本。在OnRead事件中接收Server端发送来的信息:

procedure TForm1ClientSocket1Read(Sender: TObject;

Socket: TCustomWinSocket);

begin

memo1linesadd(socketReceiveText);

end;

行了,可以运行了。

Kafka是一个分布式发布-订阅publish-subscribe消息传递系统,设计目标是快速、可伸缩和耐用冗余。

它是一个在一个较高的抽象水平上描述的但是又非常简单的系统,虽然当你更深地挖掘时会令人难以置信的技术细节。卡夫卡文档出色的解释了系统中许多设计和实现的微妙之处,所以我们不会在这里试图解释他们了。

像许多发布-订阅消息传递系统,卡夫卡能保存源消息的数据。生产者将输入写入到主题topic,而消费者则从主题topic中读取写入数据。因为卡夫卡是一个分布式系统,所以topic主题会实现跨多个节点分区和复制。

消息是简单byte数组,开发者能够使用它们存在对象的任何格式,如String或JSON和Avro,每个消息能够有一个Key,因此,生产者保证拥有相同key的消息到达同一个分区,而对主题topic的消费,可以使用多个消费者来配置消费组,每个消费组中消费者能够从他订阅的那个主题Topic所在分区子集中读取消息,这样每个消息发送给消费组中一个消费者,使用相同key的所有消息能够到达相同的消费者。

Kafka的特点是它将每个主题topic分区都看成一个日志log(一个有顺序的消息集合),一个分区中的每个消息被分配一个唯一的偏移量offset

Kafka并不试图跟踪哪个消息被哪个消费者读取,而是只是保留未被读取的消息。

Kafka保留所有消息的时间,而消费者负责跟踪它们在每个日志(日志是一个消息序列集合代表一个topic分区)中的位置,

因此Kafka能够支持大量的消费者,使用最小的代价保留大量的数据。

Kafka如何工作

假设我们正在开发一个大型多人在线游戏。在这些游戏中,玩家在一个虚拟的世界中互相合作和竞争。通常玩家互相发生贸易,比如交换物品和金钱,所以游戏开发者重要的是要确保球员不会欺骗,在下面两种情况下的交易将标记为特殊:如果贸易数量明显大于正常的球员;如果IP玩家登录是不同于过去的20场比赛使用的IP。除了对实时交易进行标记以外,我们也想加载数据到Apache

Hadoop,我们的数据,科学家们可以用它来训练和测试新算法。

基于游戏服务器内存数据缓存进行实时事件标记是最好的,能够让我们达到迅速决定,特别是对那些最活跃玩家。如果我们分区游戏服务器,我们的系统有多个游戏服务器和数据集,,包括过去登录的20个玩家和近20在内存的交易,。

我们的游戏服务器必须执行两个截然不同的角色:第一个是接受和执行用户操作,第二是实时处理贸易信息并标记可疑事件。为了有效执行第二个角色功能,每个用户整个贸易的历史事件都驻留在一个单独的服务器内存中。因为接收用户操作(第一个角色功能)的服务器可能没有他的贸易历史,这意味着我们必须通过服务器之间的消息实现第二个角色功能。为了让两个角色功能保持松散耦合,我们使用卡夫卡在服务器之间传递消息,您将看到如下:

卡夫卡有几个特性:

可伸缩性、数据分区,低延迟,并且能够处理大量不同的消费者。我们为登录和交易配置了一个Topic主题。我们把它们配置成一个topic主题的原因是:只有我们获得已经登录信息(我们可以确保玩家从他平时IP登录)后,才能确保他的交易是有效的。卡夫卡可以在在一个主题topic中维护这个前后顺序,而不是在两个topic之间。

当用户登录后进行交易,接受服务器立即发送事件到Kafka 消息是将user id作为key, 事件作为值

这能确保同一个用户的所有交易和登录发送到Kafka同样的分区 每个事件处理服务器都运行一个Kafka消费者,

其每个消费者都被配置为同样组的一部分,这样,每个服务器从少量Kafka分区读取消息,所有关于某个特定用户的数据都能发往相同事件处理服务器,当事件处理服务器从Kafka读取一个用户交易时,将这个事件加入到用户事件历史缓存本地内存缓存,这样就无需额外网络磁盘开销直接标记那些可以事件。

重要的是我们为每个事件处理服务器创建一个分区,或者每个事件处理服务器上每核对应一个多线程应用,(记住 Kafka大部分是用少于 10,000

个分区实现所有主题topic,这样我们不能为每个用户创建一个分区,因为用户数是不断增加的。)

这好像是一种迂回方式处理事件:从游戏服务器发送事件到Kafka,

另外一台服务器读取这个事件再处理它,这种设计解耦了两种角色功能,允许我们为每个角色功能安排其需要的容量与能力。另外,这样做不会增加处理时间,因为Kafka是设计为高吞吐量和低延迟的,即使只有一个小的三台节点服务器的集群环境,也能每秒处理接近一百万个事件,平均延迟只有3ms

当服务器标识出一个事件作为可疑,它会发送这个标记了的事件到新的Kafka

topic,比如其主题名称为Alerts,这时报警服务器或仪表监控服务器会接受到这个事件,同时另外一个单独过程会从Alerts主题中读取这个事件,将它写入到Hadoop进行更进一步分析。

因为Kafka并不跟踪确认每个消费者的消息,它就能用很少的性能影响处理成千上万的消费者。Kafka甚至可以处理批量消费者:每一个小时处理过程唤醒激活处理一个队列中所有消息,根本就不会影响系统的吞吐量或延迟。

DABAN RP主题是一个优秀的主题,极致后台体验,无插件,集成会员系统
网站模板库 » asp.net中回发是怎么回事?高手解答下,越详细越好,言简意赅容易明白的亦可,谢啦

0条评论

发表评论

提供最优质的资源集合

立即查看 了解详情