Linux за българи: Форуми

Програмиране => Web development => Темата е започната от: VladSun в Sep 29, 2009, 23:38



Титла: Java, JavaScript и tcp streaming
Публикувано от: VladSun в Sep 29, 2009, 23:38
Наложи ми се да работя със услуга, която на определен TCP порт "хвърля" събития от друга услуга. Тези събития трбва да се следят от AJAX уеб интерфейс.
Избрах си streaming от всичките предложения в http://en.wikipedia.org/wiki/Comet_(programming)
Пробвал съм другите, JS/HTTP базирани решения, но не ми харесват.
Та ... на първа стъпка, това сътворих:
EventListener.java
Код
GeSHi (Java):
  1. import java.applet.Applet;
  2. import java.net.Socket;
  3. import java.net.URL;
  4. import java.io.*;
  5. import java.awt.*;
  6.  
  7. import java.net.MalformedURLException;
  8.  
  9. public class EventListener extends Applet implements Runnable
  10. {
  11.    protected int       port = 0;
  12.    protected Socket    sock = null;
  13.  
  14.    protected String    eventHandlerObject = null;
  15.  
  16.    protected BufferedReader        socketReader = null;
  17.    protected OutputStreamWriter    socketWriter = null;
  18.  
  19.    protected TextArea  textArea = null;
  20.    protected boolean   debugMode = false;
  21.    protected boolean   autoConnect = false;
  22.  
  23.  
  24.    @Override
  25.    public void init()
  26.    {
  27.        this.debugMode = (this.getParameter("debugMode") != null);
  28.        this.autoConnect = (this.getParameter("autoConnect") != null);
  29.  
  30.        if (this.debugMode)
  31.        {
  32.            this.setLayout(null);
  33.            this.textArea = new TextArea();
  34.            this.textArea.setBounds(new Rectangle(0, 0, 800, 450));
  35.            this.add(this.textArea);
  36.        }
  37.  
  38.        if (Integer.parseInt(this.getParameter("port")) != 0)
  39.        {
  40.            this.port = Integer.parseInt(this.getParameter("port"));
  41.        }
  42.        else
  43.        {
  44.            this.log("Port is undefined or not integer");
  45.            return;
  46.        }
  47.  
  48.        if (this.getParameter("handler") == null)
  49.        {
  50.            this.log("Handler is undefined");
  51.            return;
  52.        }
  53.  
  54.        this.eventHandlerObject = this.getParameter("handler");
  55.  
  56.        if (this.autoConnect)
  57.        {
  58.            this.connect();
  59.        }
  60.    }
  61.  
  62.    public void setHandler(String handler)
  63.    {
  64.        if (handler != null && handler.length() != 0)
  65.            this.eventHandlerObject = handler;
  66.    }
  67.  
  68.    public boolean disconnect()
  69.    {
  70.        if (this.sock.isClosed())
  71.            return true;
  72.  
  73.        try
  74.        {
  75.            this.sock.close();
  76.        }
  77.        catch (IOException e)
  78.        {
  79.            this.log(e);
  80.            this.handle("onDisconnectFailure", e.toString());
  81.            return false;
  82.        }
  83.        this.handle("onDisconnectSuccess");
  84.        return true;
  85.    }
  86.  
  87.    public boolean connect()
  88.    {
  89.        if (this.sock != null && this.sock.isConnected())
  90.        {
  91.            try
  92.            {
  93.                this.sock.close();
  94.            }
  95.            catch (IOException e)
  96.            {
  97.                this.log(e);
  98.                return false;
  99.            }
  100.        }
  101.  
  102.        try
  103.        {
  104.            sock = new Socket(this.getCodeBase().getHost(), this.port);
  105.        }
  106.        catch (IOException e)
  107.        {
  108.            this.log(this.getCodeBase().getHost() + ":" + this.port);
  109.            this.log(e);
  110.            this.handle("onConnectFailure", e.toString());
  111.            return false;
  112.        }
  113.  
  114.        try
  115.        {
  116.            this.socketWriter = new OutputStreamWriter(sock.getOutputStream());
  117.            this.socketReader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
  118.        }
  119.        catch (IOException e)
  120.        {
  121.            this.log(e);
  122.            this.handle("onConnectFailure", e.toString());
  123.            return false;
  124.        }
  125.  
  126.        this.handle("onConnectSuccess");
  127.  
  128.        Thread sockerReaderThread = new Thread(this);
  129.        sockerReaderThread.start();
  130.  
  131.        return true;
  132.    }
  133.  
  134.    public boolean write(String message)
  135.    {
  136.        if (this.sock == null || !this.sock.isConnected())
  137.        {
  138.            this.handle("onConnectionFailure");
  139.            return false;
  140.        }
  141.  
  142.        try
  143.        {
  144.            socketWriter.write(message);
  145.            socketWriter.flush();
  146.        }
  147.        catch (IOException e)
  148.        {
  149.            this.log(e);
  150.            this.handle("onWriteFailure", e.toString());
  151.            return false;
  152.        }
  153.        this.handle("onWriteSuccess");
  154.        return true;
  155.    }
  156.  
  157.    @Override
  158.    public void run()
  159.    {
  160.        String line;
  161.  
  162.        try
  163.        {
  164.            while (true)
  165.            {
  166.                if (this.sock == null || !this.sock.isConnected())
  167.                {
  168.                    this.handle("onConnectionFailure");
  169.                    return;
  170.                }
  171.  
  172.                if ( (line = this.socketReader.readLine()) != null)
  173.                {
  174.                    this.log(line);
  175.                    this.handle("onReadSuccess", line);
  176.                }
  177.            }
  178.        }
  179.        catch (IOException e)
  180.        {
  181.            this.log(e);
  182.            this.handle("onReadFailure", e.toString());
  183.        }
  184.    }
  185.  
  186.    @Override
  187.    public void stop()
  188.    {
  189.        if (this.sock.isClosed())
  190.            return;
  191.  
  192.        try
  193.        {
  194.            this.sock.close();
  195.        }
  196.        catch (IOException e)
  197.        {
  198.            this.log(e);
  199.        }
  200.    }
  201.  
  202.    public void handle(String handler, String data)
  203.    {
  204.        if (handler == null)
  205.            return;
  206.  
  207.        try
  208.        {
  209.            this.getAppletContext().showDocument(new URL("javascript:"+ this.eventHandlerObject + "['" + handler + "']" + "(\"" + data +"\")"));
  210.        }
  211.        catch (MalformedURLException e)
  212.        {
  213.            this.log(e);
  214.        }
  215.    }
  216.  
  217.    public void handle(String handler)
  218.    {
  219.        if (handler == null)
  220.            return;
  221.  
  222.        try
  223.        {
  224.            this.getAppletContext().showDocument(new URL("javascript:" + this.eventHandlerObject + "['" + handler + "']()"));
  225.        }
  226.        catch (MalformedURLException e)
  227.        {
  228.            this.log(e);
  229.        }
  230.    }
  231.  
  232.    public void log(String message)
  233.    {
  234.        if (this.debugMode && this.textArea != null)
  235.        {
  236.            textArea.append(message + "\n");
  237.        }
  238.    }
  239.  
  240.    public void log(Exception ex)
  241.    {
  242.        this.log(ex.toString());
  243.    }
  244. }

baseHandler.js
Код
GeSHi (Javascript):
  1. Ext.namespace("Ext.EventListener");
  2.  
  3. Ext.EventListener.BaseHandler = function(config)
  4. {
  5.    Ext.apply(this, config);
  6.    Ext.EventListener.BaseHandler.superclass.constructor.call(this);
  7.    this.addEvents(
  8.        'connectSuccess',
  9.        'readSuccess',
  10.        'writeSuccess',
  11.        'disconnectSuccess',
  12.  
  13.        'connectFailure',
  14.        'readFailure',
  15.        'writeFailure',
  16.        'disconnectFailure',
  17.  
  18.        'readResponse',
  19.  
  20.        'receivedResponse',
  21.        'receivedEvent'
  22.    );
  23.  
  24.    this.eventListener = window.document[config['listenerName']];
  25. }
  26.  
  27. Ext.extend(Ext.EventListener.BaseHandler, Ext.util.Observable,
  28. {
  29.    eventListener       : null,
  30.  
  31.    request             : function (msg)
  32.    {
  33.        this.eventListener.write(msg);
  34.    },
  35.  
  36.    connect             : function ()
  37.    {
  38.        this.eventListener.connect();
  39.    },
  40.  
  41.    onConnectSuccess    : function ()
  42.    {
  43.        this.fireEvent("connectSuccess", this);
  44.    },
  45.    onReadSuccess       : function (data)
  46.    {
  47.        this.fireEvent("readSuccess", data, this);
  48.    },
  49.    onWriteSuccess      : function ()
  50.    {
  51.        this.fireEvent("writeSuccess", this);
  52.    },
  53.    onDisconnectSuccess : function ()
  54.    {
  55.        this.fireEvent("disconnectSuccess", this);
  56.    },
  57.  
  58.    onConnectFailure    : function (msg)
  59.    {
  60.        this.fireEvent("connectFailure", msg, this);
  61.    },
  62.    onReadFailure       : function (msg)
  63.    {
  64.        this.fireEvent("readFailure", msg, this);
  65.    },
  66.    onWriteFailure      : function (msg)
  67.    {
  68.        this.fireEvent("writeFailure", msg, this);
  69.    },
  70.    onDisconnectFailure : function (msg)
  71.    {
  72.        this.fireEvent("disconnectFailure", msg, this);
  73.    }
  74. });

index.php
Код
GeSHi (HTML):
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2.    <title></title>
  3.    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  4.    <script type="text/javascript" src="/scripts/ext/ext-base.js"></script>
  5.    <script type="text/javascript" src="/scripts/ext/ext-debug.js"></script>
  6.    <script type="text/javascript" src="/scripts/baseHandler.js"></script>
  7.    <script>
  8.        var handler = null;
  9.  
  10.        Ext.onReady(function ()
  11.        {
  12.            handler = new Ext.EventListener.BaseHandler(
  13.            {
  14.                listenerName    : 'asterisk',
  15.            });
  16.  
  17.            handler.connect();
  18.  
  19.            handler.on(
  20.            {
  21.                connectSuccess  :
  22.                {
  23.                    scope   : handler,
  24.                    fn      : function ()
  25.                    {
  26.                        alert("Connected");
  27.                    }
  28.                },
  29.  
  30.                readSuccess :
  31.                {
  32.                    scope   : handler,
  33.                    fn      : function (text)
  34.                    {
  35.                        alert(text);
  36.                    }
  37.                }
  38.            })
  39.        });
  40.  
  41.    </script>
  42. </head>
  43.    <applet code="EventListener.class" archive="EventListener.jar" width="0" height="0" name="asterisk">
  44.        <param name="port" value="5038">
  45.        <param name="handler" value="handler">
  46.    </applet>
  47. </body>
  48. </html>

Използвам self-signed applet (мисля, че трябва да е така за да може да отваря сокети изън localhost, но не съм сигурен). Java-та не ми е силната страна, а съм сигурен, че тук има хора, които биха ме подпомогнали с градивна критика.

Благодаря предварително!

ПП: Прикачам, jar файла, но с добавено разширение .zip (файлът не е ZIP-нат наистина), защото такива са разрешенията за форума.