AJAX实例之股票实时信息显示

来源:互联网 发布:软件界面设计要求特性 编辑:程序博客网 时间:2024/04/29 00:36

实例内容

             实例的具体内容是:服务端每隔指定时间产生股价,并计算涨幅,然后以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,url,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', '', callback, 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。

原创粉丝点击