zoukankan      html  css  js  c++  java
  • 基于Web的数据推送技术(转)

    基于Web的数据推送技术

    对于实时性数据显示要求比较高的系统,比如竞价,股票行情,实时聊天等,我们的解决方案有以下几种。
    1. HTTP请求发送模式,一般可以基于ajax的请求,比如每3秒一次访问下服务器,实现过程比较简单,只要需求不是太变态,基本上认为这个时间延迟可以接 受的话,那完全没有问题,不过服务端的压力有点大,访问量多的话,那就很容易挂了,这个也是为什么很多聊天室有人数限制的原因了,我怀疑一个聊天室就有一 台服务器撑着。

    2.基于socket的推送方式,这个是真正的推送技术,服务器压力相对较小,但是要保持和客户端通讯的socket,以 便需要的时候可以拿到这个socket给用户发送消息。但是保持那么的socket也是耗资源的。而且郁闷的是我们的网页是不支持socket接受消息 的,不过可以通过flash或者applet来作为socket的客户端,他们都是可以嵌入到网页中的。浏览器的支持类型来说,还是flash会更友好 点。

    下面给个例子,是服务器端的,主要功能是每3秒钟向客户端推送个时间

    Server.java
    ----------------------------------------------
    /**
    *
    */
    package com.spell;

    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Timer;

    /**
    * @author Administrator
    *
    */
    public class Server {
    private int PORT = 9000;
    private ServerSocket ss = null;
    private Timer timer = new Timer();

        public Server() {
    try {
    ss = new ServerSocket(PORT);
    System.out.println("server start");
    } catch (IOException e) {
    e.printStackTrace();
    }
    }

        /**
         * @param args
         */
    public static void main(String[] args) {
    Server server = new Server();
    server.startup();

        }

        public void startup() {
    Socket s = null;
    while (true) {
    try {
    s = ss.accept();
    Handler handler = new Handler(s);
    timer.schedule(handler, 1000, 3000);
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }


    Handler.java处理具体的事务
    -----------------------------------------
    /**
    *
    */
    package com.spell;

    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.util.Date;
    import java.util.TimerTask;

    /**
    * @author Administrator
    *
    */
    public class Handler extends TimerTask {
    private Socket socket;

        public Handler(Socket socket) {
    this.socket = socket;

        }

        @Override
    public void run() {
    String nowTime = (new Date()).toLocaleString();
    try {
    if (socket != null && socket.isConnected()) {
    // 这里打个擦边球,先发送个紧急的数据包,如果发送发送了异常,说明客户端已经关闭了socket连接了,进入异常处理程序
    socket.sendUrgentData(0xFF);
    System.out.println(nowTime);
    PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket
    .getOutputStream()));
    pw.append(nowTime);
    pw.append(" ");
    pw.flush();
    }
    } catch (IOException e) {
    try {
    socket.close();
    } catch (IOException e2) {
    }
    this.cancel();
    }

        }

    }



    applet程序:
    -------------------------------------------------
    /**
    *
    */
    package com.spell;

    import java.applet.Applet;
    import java.awt.Label;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.Socket;

    /**
    * 此程序eclipse运行良好,但是在IE中引入该Applet就出错了,提示access denied
    * 是由于客户端的安全策略引起的,看来还是要用flash比较靠谱
    *
    */
    public class SocketApplet extends Applet implements Runnable {
    Label text = new Label();
    private Socket socket;
    private BufferedReader br;

        public SocketApplet() {

        }

        public void init() {
    text.setText("time begin");
    add(text);
    try {
    socket = new Socket("172.21.1.112", 9000);
    // socket = new Socket("127.0.0.1", 9000);
    br = new BufferedReader(new InputStreamReader(socket
    .getInputStream()));
    text.setText("socket setup ok ...");
    // 初始化完毕,启动线程处理
    new Thread(this).start();
    } catch (Exception e) {
    text.setText(e.getMessage());
    }
    }

        public void run() {
    while (true) {
    try {
    text.setText(br.readLine());
    } catch (IOException e) {

                }
    }
    }

    }

    ---flash socket的解决方案
    flex代码:

    <?xml version="1.0" encoding="utf-8"?>
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
    <fx:Declarations>
    <!-- 将非可视元素(例如服务、值对象)放在此处 -->
    </fx:Declarations>
    <s:Label x="157" y="98" text="my time" height="22" width="230" id="message"/>
    <s:Button x="153" y="126" label="begin socket" id="btn" click="changeText()"/>
    <s:Button x="153" y="155" label="end socket" id="btn2" enabled="false" click="endSocket()"/>


    <fx:Script>
    <![CDATA[
    var mysocket:Socket;
    var host:String="127.0.0.1";
    var str:String;
    var port:int=9000;
    public function changeText():void {
    btn.enabled=false;
    btn2.enabled=true;
    mysocket=new Socket();
    mysocket.addEventListener( ProgressEvent.SOCKET_DATA, onSocketData );
    mysocket.connect(host,port);
    }

    private function onSocketData( event:ProgressEvent ):void {
    trace( "Socket received " + mysocket.bytesAvailable + " byte(s) of data:" );
    var data:String = mysocket.readUTFBytes(mysocket.bytesAvailable);
    message.text=data;
    }


    public function endSocket():void {
    mysocket.close();
    btn.enabled=true;
    btn2.enabled=false;
    }
    ]]>
    </fx:Script>
    </s:Application>

    概念引申阅读:
    http://www.javaeye.com/topic/701526

  • 相关阅读:
    [oracle] Oracle存储过程里操作BLOB的字节数据的办法,例如写入32位整数
    [C#] 将NLog输出到RichTextBox,并在运行时动态修改日志级别过滤
    [Java] 绕过证书验证调 HTTPS 接口时报 “SSLHandshakeException: DHPublicKey does not comply to algorithm constraints”的解决办法
    [Chrome插件] SelectJd(京东自营筛选器) v1.0.0 发布
    全面解决.Net与Java互通时的RSA加解密问题,使用PEM格式的密钥文件
    [C#] 解决Silverlight反射安全关键(SecuritySafeCritical)时报“System.MethodAccessException: 安全透明方法 XXX 无法使用反射访问”的问题
    升级SilverLight为5.1.50907.0后,VS调试时报“无法启动调试--未安装 Silverlight Developer 运行时。请安装一个匹配版本”的处理办法
    JavaScript 定义类的最佳写法——完整支持面向对象(封装、继承、多态),兼容所有浏览器,支持用JSDuck生成文档
    JavaScript 实现命名空间(namespace)的最佳方案——兼容主流的定义类(class)的方法,兼容所有浏览器,支持用JSDuck生成文档
    Javascript自动化文档工具JSDuck在Windows下的使用心得
  • 原文地址:https://www.cnblogs.com/tonykan/p/3467048.html
Copyright © 2011-2022 走看看