Package org.snova.framework.proxy.c4.ws

Source Code of org.snova.framework.proxy.c4.ws.IOWorker

/**
*
*/
package org.snova.framework.proxy.c4.ws;

import java.net.InetSocketAddress;
import java.util.concurrent.TimeUnit;

import org.arch.buffer.Buffer;
import org.arch.config.IniProperties;
import org.arch.encrypt.RC4;
import org.arch.misc.crypto.base64.Base64;
import org.arch.util.NetworkHelper;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseDecoder;
import org.snova.framework.config.SnovaConfiguration;
import org.snova.framework.proxy.c4.CumulateReader;
import org.snova.framework.util.SharedObjectHelper;

/**
* @author yinqiwen
*
*/
public class IOWorker extends SimpleChannelUpstreamHandler
{
  WSTunnelService         serv;
  int                     index;
  ChannelFuture         conn;
  Buffer                 unsentContent  = new Buffer();
  boolean                 connected;
  private CumulateReader  cumulater   = new CumulateReader();
 
  public IOWorker(WSTunnelService wsTunnelService, int i)
  {
    this.serv = wsTunnelService;
    this.index = i;
  }
 
  synchronized void write(Buffer buf)
  {
    unsentContent.write(buf, buf.readableBytes());
    if (connected)
    {
      tryWriteCache();
    }
    else
    {
      System.out.println("#######Not connected!");
    }
  }
 
  private synchronized void tryWriteCache()
  {
    if (connected && unsentContent.readable())
    {
      byte[] tmp = new byte[unsentContent.readableBytes()];
      unsentContent.read(tmp);
      unsentContent.clear();
      conn.getChannel().write(ChannelBuffers.wrappedBuffer(tmp));
    }
  }
 
  public void start()
  {
    if (null != conn && conn.getChannel().isConnected())
    {
      return;
    }
    connected = false;
    IniProperties cfg = SnovaConfiguration.getInstance().getIniProperties();
    StringBuilder buffer = new StringBuilder();
    buffer.append("GET ").append(serv.server.url.getPath())
            .append("HTTP/1.1\r\n");
    buffer.append("Upgrade: WebSocket\r\n");
    String enc = cfg.getProperty("C4", "Encrypter", "RC4");
    if (enc.equalsIgnoreCase("RC4"))
    {
      String key = cfg.getProperty("Misc", "RC4Key");
      RC4.setDefaultKey(key);
      byte[] tmp = RC4.encrypt(key.getBytes());
      buffer.append("RC4Key:").append(Base64.encodeToString(tmp, false)).append("\r\n");
    }
    String host = serv.server.url.getHost();
    int port = serv.server.url.getPort();
    if (port < 0)
    {
      port = 80;
    }
    buffer.append("Host: ").append(host).append(":").append(port)
            .append("\r\n");
    buffer.append("Connection: Upgrade\r\n");
    buffer.append("ConnectionIndex:").append(index).append("\r\n");
    buffer.append("UserToken:").append(NetworkHelper.getMacAddress())
            .append("\r\n");
    buffer.append("Keep-Alive:")
            .append(cfg.getIntProperty("C4", "WSConnKeepAlive", 300))
            .append("\r\n\r\n");
    final ChannelBuffer request = ChannelBuffers.wrappedBuffer(buffer
            .toString().getBytes());
   
    conn = SharedObjectHelper.getClientBootstrap().connect(
            new InetSocketAddress(host, port));
    conn.getChannel().getPipeline()
            .addLast("codec", new HttpResponseDecoder());
    conn.getChannel().getPipeline().addLast("handler", this);
    conn.addListener(new ChannelFutureListener()
    {
      public void operationComplete(ChannelFuture future)
              throws Exception
      {
        if (future.isSuccess())
        {
          future.getChannel().write(request);
        }
      }
    });
  }
 
  @Override
  public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
          throws Exception
  {
   
    if (!connected)
    {
      HttpResponse res = (HttpResponse) e.getMessage();
      System.out.println("####recv " + res);
      if (res.getStatus().getCode() == 101)
      {
        conn.getChannel().getPipeline().remove("codec");
        connected = true;
        tryWriteCache();
      }
      else
      {
        conn.getChannel().close();
        SharedObjectHelper.getGlobalTimer().schedule(new Runnable()
        {
          public void run()
          {
            start();
          }
        }, 1, TimeUnit.SECONDS);
      }
    }
    else
    {
      ChannelBuffer content = (ChannelBuffer) e.getMessage();
      cumulater.fillResponseBuffer(content);
    }
   
  }
 
  @Override
  public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
          throws Exception
  {
   
    if (connected)
    {
      connected = false;
      SharedObjectHelper.getGlobalTimer().schedule(new Runnable()
      {
        public void run()
        {
          start();
        }
      }, 100, TimeUnit.MILLISECONDS);
    }
  }
}
TOP

Related Classes of org.snova.framework.proxy.c4.ws.IOWorker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.