在基于ASP.NET开发的B/S软件中,碰到一个需要“从服务器端主动发给客户端信息“的难题(为了合理减轻服务器端的负担和确保信息传递的时效性),如果客户端只用IE来访问软件,此时数据传输是基于HTTP协议的,我认为在这个条件下是无法实现“从服务器端主动发给客户端信息”的,即使为客户端开发相应的插件(ActiveX),我对.NET的Web Service、Remoting技术了解不深,非常感谢由此经验的大侠给点意见,感激不尽!

解决方案 »

  1.   

    ActiveX 我不知道行不行 但是这个肯定是要在客户端打开一个网络端口监听的.所谓的Push模式.
      

  2.   

    绝对主动,是不可能的。。可以用javascript让客户端IE定时postback到服务器。
      

  3.   

    参考::
    http://www.microsoft.com/china/community/Column/62.mspx
      

  4.   

    Server push——崭新的“推”技术,它是一种先进的服务器和客户机之间的通信连接方式,利用在服务器端的CGI脚本程序把数据源源不断地推向客户机,从而使客户机和服务器之间的交互性能大大提高。在中国计算机报电脑工作室中有介绍Server push,我们也搜集整理一些关于Server push的资料,供大家参考。    首先也来看看传统Client pull的工作方式,Client pull以 这样的HTML文档头来自动刷新页面,使用户的浏览器能不断地刷新以接受服务器传回的内容,那么用户就不得不忍受等待“tmie”值的痛苦,相信在中国电信的网速之下,大家对这个深有体会。    采用了Server push技术的服务器在客户机做出一个请求后,和客户机建立一个永久的连接,然后服务器会根据客户机的请求不断把数据包推向客户,这个推的过程是不间断的。由服务器推向客户机的数据在客户机的浏览器上会不断产生新的内容,而且不会产生Client pull那样的HTML文档头,从而大大减少了延迟的时间,向(服务器响应——客户机请求)同步迈进了一步。    实现Server push技术非常简单。Server push在服务器的CGI脚本声明HTML文档类型时,把传统的content-type:text/html改为content-type:multipart/x-mixed-replace;boundary=BOUNDARY这样的文档类型,就会反馈给用户一个Server push类型的连接。这是Server push和Client pull的根本区别。如果CGI脚本中提供了这样的HTML文档头,服务器在处理客户机请求调用CGI脚本程序时,就会把CGI脚本中指定的数据强行推给客户机。    Server push在生成页面时会采用很多的技巧来处理用户端浏览器页面的生成。主程序和传统方式没有本质的区别,但记得在脚本中加入print“Content-Type:multipart/x-mixed-replace;bound
      

  5.   

    参考:
    http://dev.csdn.net/article/9/article/09/09787.shtm
    http://www.knowsky.com/3742.html
      

  6.   

    realljx,你的话我很受启发啊,我想到这样一个思路,前提是客户端只使用IE,开发一个ActiveX控件,客户端下载安装这个控件,该控件实现通过TCP/IP协议与服务器端通信,服务器端发送的信息就可以直接通过IE反馈给客户了,应该是可行的(对ActiveX不熟,没弄过)。
    另外,据我了解的信息.NET采用了些新技术逐步取代COM的应用了,一部分就是基于组件的开发这种概念,其他的有人了解吗?
      

  7.   

    我们在前面文章中讨论客户机与服务器的数据交互时,数据流的方向总是从服务器到客户机,很少涉及到客户机向服务器发送请求并处理返回信息的问题。实际上,在电子商务中,客户机向服务器发送数据也是一个重要的环节,如用户填写的货物订单等。 
    在传统的实现方案中,用户端只要在订单中做出微小的变动,就要向服务器发送消息,要求更新数据。这样就增加了服务器和网络的负载,降低了工作效率。更有效的工作方式是在客户机端对变更的信息进行缓存,然后分批定量地发送给服务器,这样一些不确定的修改信息都首先存储在客户机,只有那些确定的需要更新的数据才会发送出去,从而避免了网络和服务器做许多无谓的操作。 
    2、基于XML的C/S 
    使用XML进行C/S间的通信是一种高效的工作方式。首先在客户机对XML数据打包,然后以XML数据包为单元发送给服务器,服务器在处理完数据之后返回消息,客户机接收到消息后执行其他操作,从而结束一次通信周期。 
    具体实现步骤如下: 
    ● 客户机构造一个XMLDOM对象,作为发送XML数据的载体; 
    ● 客户机创建一个XMLHTTP对象,该对象包括多种方法和属性,可以发送XML数据到服务器上的应用程序(如ASP页面),同时准备接收响应信息; 
    ● 客户机将XML数据包转载到XMLHTTP对象上并发送给ASP页面; 
    ● 服务器执行ASP,并创建一个服务器端XMLDOM对象来接收XML数据; 
    ● ASP把数据包装载到服务器端的XMLDOM对象上; 
    ● ASP对XML数据进行必要的处理,并返回确认消息; 
    ● 客户机接收响应消息,执行下一步操作。 
    3、向服务器发送数据 
    客户机的首要任务是构造XML数据包。XMLDOM作为数据包的载体其数据来源可以是任何XML文档或是XML文档的片段(如XML数据岛),甚至可以是使用loadXML方法接收用户输入信息后动态生成的XML文档。 
      

  8.   

    XmlHttp.htm
    <html>
     <head>
      <title>Lion互动网络==》在客户端用XmlHttp取得服务器端的DataSet数据</title>
      <meta http-equiv="Pragma" content="no-cache">
     </head>
     <body>
      <INPUT id="Button1" onclick="GetDataSet()" type="button" value="取得XmlHttp.Aspx中的DataSet以Xml形式显示"
       name="Button1">
      <div id="abc"><FONT face="宋体"></FONT></div>
    <script language="jscript">
    function CreateXMLHTTP()
    {
     try{return new ActiveXObject('MSXML2.XMLHTTP');}catch(x){}
     try{return new ActiveXObject('Microsoft.XMLHTTP');}catch(x){}
     throw(new Error(-1,'不能创建XMLHTTP'));
    }
    function GetDataSet()

     var xmlhttp = CreateXMLHTTP();
     var url = document.location.href;
     url = url.substring(0,url.lastIndexOf("\/")+1)+"XMLHTTP.aspx";
     xmlhttp.open("GET",url,false)
     xmlhttp.setRequestHeader("Content-Type","text/xml")
     xmlhttp.send()
     abc.innerText = (xmlhttp.responseXML.xml);
     
    }
    </script>
     </body>
    </html> XMLHTTP.aspx
    <%@ Page language="c#" Codebehind="XMLHTTP.aspx.cs" Src="XMLHTTP.aspx.cs" AutoEventWireup="false" Inherits="Exam.WebForm1" %>XMLHTTP.aspx.cs
    using System;
    using System.Collections;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Web;
    using System.Web.SessionState;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.HtmlControls;namespace Exam
    {
     /// <summary>
     /// WebForm1 的摘要说明。
     /// </summary>
     public class WebForm1 : System.Web.UI.Page
     {
      private void Page_Load(object sender, System.EventArgs e)
      {   
       // 在此处放置用户代码以初始化页面
       
       System.Data.DataTable DT = new System.Data.DataTable("temptable");
       DT.Columns.Add("ID",typeof(int));
       DT.Columns.Add("Name",typeof(string));
       DT.Columns.Add("AddTime",typeof(DateTime));
       DT.Columns[0].AutoIncrement = true;
       DT.Columns[0].AutoIncrementSeed = 1;
       DT.Columns[0].AutoIncrementStep = 1;
       for(int i=0;i<20;i++)
       {
        System.Data.DataRow dr= DT.NewRow();
        dr[1] = "欢迎光临Lion互动网络,第 "+ (i+1) +" 行";
        dr[2] = System.DateTime.Now.AddDays(i);
        DT.Rows.Add(dr);
       }
       System.Data.DataSet ds = new System.Data.DataSet("Root");
       ds.Tables.Add(DT);
       Response.Buffer=true;
       Response.CacheControl="no-cache";
       Response.ContentType = "text/xml";
       Response.Clear();
       Response.Write("<?xml version='1.0' encoding='gb2312'?>");
       Response.Write(ds.GetXml());
       Response.End();
       DT.Clear();
       DT.Dispose();
       ds.Clear();
       ds.Dispose();
       
      }  #region Web 窗体设计器生成的代码
      override protected void OnInit(EventArgs e)
      {
       //
       // CODEGEN: 该调用是 ASP.NET Web 窗体设计器所必需的。
       //
       InitializeComponent();
       base.OnInit(e);
      }
      
      /// <summary>
      /// 设计器支持所需的方法 - 不要使用代码编辑器修改
      /// 此方法的内容。
      /// </summary>
      private void InitializeComponent()
      {    
       this.Load += new System.EventHandler(this.Page_Load);  }
      #endregion
     }
    }
      

  9.   

    非常感谢roapzone(宗璞),我先去看一下,如果不小心搞出来,一定公布出来。