有状态和无状态有什么区别?


86

MVC上的书籍和文档只是使用有状态和无状态术语而堆积。老实说,我只是无法理解它的意思,书在说什么。他们没有提供一个示例来了解这两种状态中的任何一种,而不是仅仅告诉HTTP是无状态的,并且使用ASP.NET MVC时,Microsoft会与之相伴。我是否缺少一些基本知识,因为我无法理解什么是有状态的,为什么是有状态的,无状态也是如此?

我想通过一个简单而简短的示例来讨论按钮或文本框之类的控件。

Answers:


40

无状态意味着HTTP尚未内置对状态的支持。例如,您无法存储用户是否已登录或进行了其他操作。

最常见的解决方案是使用会话来解决该问题。这意味着您必须能够在每个响应或请求中包括一个会话标识符。这可以通过创建会话cookie或在所有链接中包括会话标识符来完成。

WebForms尝试使所有这些透明(使用ViewState),而MVC强制您手动处理它。

在您的示例中,您提到了Buttons和TextBoxes。让他们保持状态的最简单方法就是停止回发整个页面。MVC获得了对ajax(通过jQuery)的出色支持,如果您只想在当前页面上做某事,我建议您使用ajax。


3
这意味着,如果我登录到网站,则我访问的每个页面都将在通过会话标识符或会话cookie呈现内容之前重新检查身份验证?
Pankaj Upadhyay

3
对,那是正确的。
jgauffin

那么无状态是好是坏?
卢卡斯-Better Coding Academy

1
@ think123:由于您不必管理状态(例如,负载平衡等要容易得多),因此性能更高。由于您必须管理人工状态,因此这变得更加复杂。
jgauffin

5
@jgauffin:表演者在这里是错误的单词。无状态是高性能的,因为你没有缓存的状态,并要反复看它的机会。它具有更多的可扩展性 ; 这就是负载平衡的来源,而可伸缩性带来的好处可以弥补系统足够大时的性能损失。
梅森·惠勒

108

无状态-程序不维护任何内存(状态)

有状态-程序具有内存(状态)

为了说明状态的概念,我将定义一个有状态的函数和一个状态的函数

无状态

//The state is derived by what is passed into the function

function int addOne(int number)
{
    return number + 1;
}

有状态的

//The state is maintained by the function

private int _number = 0; //initially zero 

function int addOne()
{
    _number++;
    return _number;
}

正如其他人所说,http本质上是无状态的。因此状态必须内置到您的应用程序中。

想象一下在Web上有一个客户端浏览器与服务器进程通信的请求。为了维持无状态http协议上的状态,浏览器通常会在每次请求时发送会话标识符到服务器。对于每个请求,服务器都将像“啊,这家伙”。然后可以基于此会话ID在服务器端内存或数据库中查找状态信息。

在纯无状态的环境中,您不需要此会话ID。每个请求将包含服务器需要处理的所有信息。但是许多应用程序需要维护状态,以跟踪会话是否已通过身份验证以查看某些内容或跟踪用户在做什么。您不想为每个请求通过网络发送用户凭证。


快速问题:如果会话ID被另一个用户使用(即被盗),服务器将不知道这是其他人吗?
mihai 2014年

4
没错 有多种保护用户身份的方法,例如使用https或httponly cookie。但是,如果用户的计算机受到威胁,则攻击者可能使服务器欺骗以为他们是用户。
编码器2014年

2
+1可获得清晰明快的代码示例。我更加坚信,大多数复杂的IT术语只能在上下文中理解。
塞巴斯蒂安2015年

会话ID可能被盗的原因之一是您必须小心,而CMS之类的应用程序或OAuth之类的应用程序的构建方式会使此操作更加困难。
Elin

4
每个请求的服务器会像“啊,它的这个家伙” -更好地说,在所有其他的例子,我已经看到了
拉斐尔Eyng


3

以我的简单见解,ASP.NET(有状态)和ASP.NET-MVC(无状态)之间的区别可以隔离到以下事实:第一个提供服务器端控件,而另一个不提供服务器端控件。

值得注意的是,ASP.NET Web窗体方法旨在过渡用于事件模型驱动模型中的旧VB和VC ++程序员,从而使他们能够很好地快速学习遵循相同事件模型范例的Web编程,例如单击一个按钮,瞧,您会触发一个事件!您现在要做的就是在事件处理程序中编写代码。因此,ASP.NET需要具有诸如视图状态和回发之类的概念来监视每次往返的服务器端控件的状态。

但是,ASP.NET-MVC不使用服务器端控件,因此不必维护状态。MVC模型将问题域划分为三个分区,以便以简化的方式将数据传递到客户端。

总之,在有状态和无状态方面,服务器端控件是使它们与众不同的原因。


1

除了@coder确切答案。

状态的思想是记住以前的数据
例如,您在服务器上有一个列表控件,其值是“ A,B,C”,并且已选择“ A”。列表转到客户端浏览器。您选择“ B”。并发回到服务器。您如何知道该值已更改?

  • ASP.NET
    Microsoft 在ASP.NET中使用术语ViewState。开发人员对此有巨大的误解。
    ViewState在以下列表中保留列表的所有初始状态<input type="hidden" value="base64 encoded" />:值“ A,B,C”和标记“ A被选择”。
    然后,通过回发浏览器将ViewState和“ B is selected”发送到服务器。ASP.NET恢复列表的初始状态并应用新的“ B”选择。这样做是为了吸引WinForms开发人员(@Ronald提到)。在Web服务器上,您可以订阅列表更改listObject.Changed += OnChanged

  • ASP.NET MVC
    ViewState的问题是大小。多年来,.NET开发人员被迫传输数千字节的无用信息,例如每次往返20个控件的状态。
    新方法是只发送新的和小的“ B”值。
    或者,如果您要跟踪从“ A”到“ B”的更改,请自己实施。使用javascript并发送“是A,现在是B”。或在SQL Server中按ID保存和检索状态。

  • ASP.NET MVCASP.NET实现身份验证和兑现的状态。因此,说ASP.NET MVC完全无状态是不正确的。
  • 答案中提到的内存意味着“记住”,而不是计算机内存。可以通过将数据存储在文件系统,SQL Server或计算机内存中来实现状态。

请保持建设性并解释错误,再减去
Artru

0

有状态操作会修改或需要系统的某些状态,而无状态操作则不会。

有状态文本框的示例是在StackExchange上先前编辑的注释-文本框需要显示您先前的注释,并知道它所涉及的后线程才能接受和处理您的输入。

带有mailto:标记的通用电子邮件评论表单将是无状态的文本框-它接受您的输入并将其扔到工作站的邮件应用程序中,而不会保留任何信息。


典型的“留下您的电子邮件地址和消息,我们会尽快回复您”的表单也是无状态的。当您提交表单时,服务器不在乎您从何处获得它,它只是将数据复制到某些客户服务待办事项列表中,而忽略了它。
StarWeaver 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.