实例内容
实例的具体内容是:服务端每隔指定时间产生股价,并计算涨幅,然后以json数据格式发送给客户端页面;客户端页面每隔指定时间重新获取服务端数据,解析json数据格式,并显示涨停。
实例来源于王兴魁Ajax教学视频,视频中用的是NetBeans环境Java语言编写的,使用NetBeans按教程编写不是很难,所以想着用VS2010环境C#编写,代码如下。
实例代码
Stocks.cs
Stock.cs,股票类代码:
/// <summary> ///股票信息类 /// </summary> public class Stock { public Stock(string id,string name,double yesterday) { this.sid = id; this.name = name; this.yesterday = yesterday; this.today = -1; this.highest = yesterday; this.current = yesterday; this.lowest = yesterday; } //股票ID private string sid; //股票名 private string name; //昨日股价 private double yesterday; //今日股价 private double today; //最高 private double highest; //最低 private double lowest; //当前股价 private double current; //浮动 private string range; /// <summary> /// 获取当前股价 /// </summary> /// <returns></returns> public double GetCurrent() { return current; } /// <summary> /// 获取昨日股价 /// </summary> /// <returns></returns> public double GetYesterday() { return yesterday; } /// <summary> /// 获取今日股价 /// </summary> /// <returns></returns> public double GetToday() { return today; } /// <summary> /// 获取最高股价 /// </summary> /// <returns></returns> public double GetHighest() { return highest; } /// <summary> /// 获取最低股价 /// </summary> /// <returns></returns> public double GetLowest() { return lowest; } /// <summary> /// 获取浮动值 /// </summary> /// <returns></returns> public string GetRange() { return range; } public void SetRange(string range) { this.range = range; } /// <summary> /// 设置当前股票价格 /// </summary> /// <param name="current">当前股指</param> public void SetCurrent(double current) { //计算涨幅 double range = (current - this.yesterday ) / this.yesterday ; //如果涨幅超过10% if (range > 0.1) { current = Math.Round(1.1 * this.yesterday * 100) / 100.0; } //如果跌幅超过10% if (range < -0.1) { current = Math.Round(0.9 * this.yesterday * 100) / 100.0; } this.current = current; //尚未开盘时,利用第一次的current设置开盘股价 if (this.today == -1) { this.today = current; } //根据涨跌形势设置今日股价 if (this.current > this.highest) { this.highest = this.current; } else if (this.current < this.lowest) { this.lowest = this.current; } // this.range = range.ToString("p"); } }
xmlhttp.js
xmlhttp.js,自定义的MyXMLHttpRequest"类",主要负责和服务端的交互:
// 使用封装方法的人只关心http的请求方法,URL地址,数据,成功和失败的回调方法 // 类的构造方法,主要职责是新建XMLHttpRequest对象 var MyXMLHttpRequest = function(){ var xmlhttprequest; if(window.XMLHttpRequest){ xmlhttprequest = new XMLHttpRequest(); if(xmlhttprequest.overrideMineType){ xmlhttprequest.overrideMineType("text/xml"); } }else if (window.ActiveXObject) { var activeName = ["XSXML2.XMLHTTP","Microsoft.XMLHTTP"]; for (i = 0; i < activeName.length; i++) { try { xmlhttprequest = new ActiveXObject(activeName[i]); break; } catch (e) { } } } if (xmlhttprequest == undefined || xmlhttprequest == null) { alert("xmlhttprequest对象创建失败!"); }else{ this.xmlhttp = xmlhttprequest; } } // 用户发送请求的方法 MyXMLHttpRequest.prototype.send = function(method,url,data,callback,failback){ if (this.xmlhttp != undefined || this.xmlhttp != null) { method = method.toUpperCase(); if (method != "GET" && method != "POST") { alert("HTTP请求方法必须是GET或POST"); return ; } if (url == undefined || url == null) { alert("http请求地址必须设置"); return; } var tempxmlhttp = this.xmlhttp; tempxmlhttp.onreadystatechange = function(){ if (tempxmlhttp.readyState == 4) { if (tempxmlhttp.status == 200) { var responseText = tempxmlhttp.responseText; var responseXML = tempxmlhttp.responseXML; if (callback == undefined || callback == null) { alert("没有设置处理数据正确返回的方法"); alert("返回的数据:" + responseText); } else{ callback(responseText,responseXML); } }else { if (failback == undefined || failback == null) { alert("没有设置处理数据返回失败的处理方法"); alert("Http响应码信息:" + tempxmlhttp.status + ",响应码文本信息:" + tempxmlhttp.statusText) return ; }else{ failback(tempxmlhttp.status,tempxmlhttp.statusText); } } } } // 解决缓存的转换 if (url.indexOf("?") >= 0) { url = url + "&t=" + (new Date()).valueOf(); }else{ url = url + "?t=" + (new Date()).valueOf(); } // 解决跨域问题 if (url.indexOf("http://") >= 0) { url.replace("?","&"); url = url + "Proxy?url="; } this.xmlhttp.open(method,true); // 如果是POST方式,需要设置请求头 if (method == "POST") { this.xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); } this.xmlhttp.send(data); }else{ alert("XMLHttpRequest对象创建失败,无法发送数据."); } } MyXMLHttpRequest.prototype.abort = function(){ this.xmlhttp.abort(); }
Handler.aspx
一般处理文件Handler.ashx,用于处理客户端的请求:
<%@ WebHandler Language="C#" Class="Handler" %> using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Threading; //StringBuilder所在命名空间 using System.Text; public class Handler : IHttpHandler { //定义股票字典 private Dictionary<string,Stock> stock; private System.Timers.Timer timer; /// <summary> /// 响应客户端请求 /// </summary> /// <param name="context">请求信息</param> public void ProcessRequest (HttpContext context) { context.Response.ContentType = "text/html;charset=UTF-8"; //Response.ContentType = "text/html;charset=UTF-8"; ////初始化数据 Init(); //转换为json字符串 Thread.Sleep(200); StringBuilder builder = new StringBuilder(); builder.Append("({"); //stockid数组 string[] StockId = new string[stock.Count]; //获取股票ID for (int i = 0; i < stock.Count; i++) { StockId[i] = stock.ElementAt(i).Key.ToString(); } //根据股票ID 得到股票,拼接字符串 for (int i = 0; i < stock.Count; i++) { string sid = StockId[i]; Stock tempStock = stock[sid]; builder.Append(sid).Append(":{yes:").Append(tempStock.GetYesterday()).Append(",tod:").Append(tempStock.GetToday()).Append(",high:").Append(tempStock.GetHighest()).Append(",low:").Append(tempStock.GetLowest()).Append(",cur:").Append(tempStock.GetCurrent()).Append(",ran:'").Append(tempStock.GetRange()).Append("'}"); //每个项后面再添加“,” if (i < stock.Count) { builder.Append(","); } } //尾部添加}) builder.Append("})"); //回复响应 context.Response.Write(builder); } /// <summary> /// 初始化配置数据 /// </summary> private void Init() { //新建四支股票 Stock szzs = new Stock("300001","上证指数",300); Stock pfyh = new Stock("600000","浦发银行",25); Stock gsyh = new Stock("601398","工商银行",6.5); Stock zgsy = new Stock("601857","中国石油",19.1); //设定股票字典 stock = new Dictionary<string,Stock>(); //添加股票 stock.Add("300001",szzs); stock.Add("600000",pfyh); stock.Add("601398",gsyh); stock.Add("601857",zgsy); //设置计时器参数,不要太大 timer = new System.Timers.Timer(50); timer.Enabled = true; //执行计时器函数theout Random rdm = new Random(); //每次只去一个,防止循环执行获取随机数 double mdr = rdm.NextDouble(); //timer的振荡事件,采用匿名函数方式执行 timer.Elapsed += delegate(object source,System.Timers.ElapsedEventArgs e) { //股票变动范围 //上涨浮动 double sz = mdr * 30; double pf = mdr * 0.5; double gs = mdr * 0.1; double zg = mdr * 0.3; //下跌浮动 if (mdr > 0.5) { sz = 0 - sz; } if (mdr > 0.5) { pf = 0 - pf; } if (mdr > 0.5) { gs = 0 - gs; } if (mdr > 0.5) { zg = 0 - zg; } //当前股票价格 szzs.SetCurrent(Math.Round((szzs.GetCurrent() + sz) * 100) / 100.0); pfyh.SetCurrent(Math.Round((pfyh.GetCurrent() + pf) * 100) / 100.0); gsyh.SetCurrent(Math.Round((gsyh.GetCurrent() + gs) * 100) / 100.0); zgsy.SetCurrent(Math.Round((zgsy.GetCurrent() + zg) * 100) / 100.0); }; } /// <summary> /// 实现接口自带的函数 /// </summary> public bool IsReusable { get { return false; } } }
refresh.html
refresh.html,用于发送更新股票信息的请求:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <Meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style type="text/css"> #tooltip{ display:none; position:absolute; border:1px solid black; background-color: white; z-index: 99; width:135px; } </style> <script src="Scripts/xmlhttp.js" type="text/javascript"></script> <script type="text/javascript"> var xmlhttp; var stocks; var yesNode; var todNode; var highNode; var lowNode; var curNode; var ranNode; var tooltipNode; var tooltipSid; //获取tooltip下所有节点并交互 function show() { // 获取tooltip相关的各个节点 yesNode = document.getElementById('yes'); todNode = document.getElementById('tod'); highNode = document.getElementById('high'); lowNode = document.getElementById('low'); curNode = document.getElementById('cur'); ranNode = document.getElementById('ran'); tooltipNode = document.getElementById('tooltip'); // 与服务端进行交互,获取到股票的最新消息 getStock(); // 以后每隔两秒再和服务端交互一次 setInterval(getStock,5000); } // 与服务端进行交互,获取到股票的最新消息 function getStock() { // 假如xmlhttp存在,则将上一次交互终止掉(防止两个交互返回的数据相互覆盖) if (xmlhttp) { xmlhttp.abort(); } // 利用XMLHttpRequest对象和服务器进行交互 xmlhttp = new MyXMLHttpRequest(); xmlhttp.send('GET','Handler.ashx','',failback); } function callback(responseText,responseXML) { try { // 将服务端返回的JSON数据转换成js中的对象 stocks = eval(responseText); // 更新ToolTip内容 updateToolTip(); // 遍历所有的股票 for (var sid in stocks) { var spanNode = document.getElementById(sid); // 获取某一只股票的昨天收盘价和当前价 var stock = stocks[sid]; var cur = stock.cur; var yes = stock.yes; // 将当前价设置到span的节点里面 spanNode.innerHTML = cur; // 根据当前价格设置span中的文本是红色还是绿色 if (cur >= yes) { spanNode.style.color = 'red'; } else { spanNode.style.color = 'green'; } } } catch (exception) { alert('解析服务器数据失败,错误内容为:' + exception.toString()); } } function failback(status,statusText) { alert('回调函数失败:'+ statusText); } // 显示弹出框方法 function showToolTip(aNode,event) { // 得到对应的股票代码 tooltipSid = aNode.parentNode.getElementsByTagName('span')[0].id; // 更新ToolTip内容 updateToolTip(); var myevent = window.event || event; var mouseX = myevent.clientX; var mouseY = myevent.clientY; tooltipNode.style.left = mouseX + 5 + 'px'; tooltipNode.style.top = mouseY + 5 + 'px'; tooltipNode.style.display = 'block'; } 隐藏弹出框方法 function clearToolTip() { tooltipNode.style.display = 'none'; tooltipSid = undefined; } // 更新tooltip中的内容 function updateToolTip() { if (tooltipSid) { // 当前股票的具体信息对象 var stock = stocks[tooltipSid]; // 设置昨收 var yes = stock.yes; yesNode.innerHTML = yes; // 设置今开 var tod = stock.tod; todNode.innerHTML = tod; if (tod >= yes) { todNode.style.color = 'red'; } else { todNode.style.color = 'green'; } // 设置最高 var high = stock.high; highNode.innerHTML = high; // 设置最低 var low = stock.low; lowNode.innerHTML = low; if (low >= yes) { todNode.style.color = 'red'; } else { todNode.style.color = 'green'; } // 设置当前价格和涨幅 var cur = stock.cur; curNode.innerHTML = cur; var ran = stock.ran; ranNode.innerHTML = ran; if (cur >= yes) { curNode.style.color = 'red'; ranNode.style.color = 'red'; } else { curNode.style.color = 'green'; ranNode.style.color = 'green'; } } } </script> </head> <body onload="show()"> <!--每支股票各占一个div--> <div> <a href="#" onmouSEOver="showToolTip(this,event)" onmouSEOut="clearToolTip()" >上证指数:</a> <span id="300001"></span> </div> <div> <a href="#" onmouSEOver="showToolTip(this,event)" onmouSEOut="clearToolTip()" >浦发银行:</a> <span id="600000"></span> </div> <div> <a href="#" onmouSEOver="showToolTip(this,event)" onmouSEOut="clearToolTip()" >工商银行:</a> <span id="601398"></span> </div> <div> <a href="#" onmouSEOver="showToolTip(this,event)" onmouSEOut="clearToolTip()" >中国石油:</a> <span id="601857"></span> </div> <!--tooltip框--> <div id="tooltip"> <div>昨收:<span id="yes"></span></div> <div>今开:<span id="tod"></span></div> <div>最高:<span id="high"></span></div> <div>最低:<span id="low"></span></div> <div>当前:<span id="cur"></span></div> <div>涨幅:<span id="ran"></span></div> </div> </body> </html>
运行结果
下载及预告
因为是从NetBeans环境下的Java语言转换为VS2010下的C#语言,中间碰到不少问题,这些问题会在下篇博客介绍,另附本实例的代码下载地址:http://download.csdn.net/detail/lidaasky/4927691。
原文链接:https://www.f2er.com/ajax/166875.html