Package org.bigbluebutton.deskshare.client.net

Source Code of org.bigbluebutton.deskshare.client.net.NetworkHttpStreamSender

/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.deskshare.client.net;

import java.awt.Point;
import java.io.ByteArrayInputStream;
import java.io.IOException;

import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import org.bigbluebutton.deskshare.client.ExitCode;
import org.bigbluebutton.deskshare.common.CaptureEvents;
import org.bigbluebutton.deskshare.common.Dimension;

import com.myjavatools.web.ClientHttpRequest;

import java.util.Date;
import java.text.SimpleDateFormat;

public class NetworkHttpStreamSender implements Runnable
  private static final String SEQ_NUM = "sequenceNumber";
  private static final String ROOM = "room";
  private static final String BLOCK = "blockInfo";
  private static final String EVENT = "event";
  private static final String SCREEN = "screenInfo";
  private static final String POSITION = "position";
  private static final String KEYFRAME = "keyframe";
  private static final String BLOCKDATA = "blockdata";
  private static final String MOUSEX = "mousex";
  private static final String MOUSEY = "mousey";
   private static final String BLOCKGROUP = "blockgroup";

   // The previously sent location of the mouse pointer
   private static Point previousMouseLocation = new Point(0,0);

  private static final String USE_SVC2 = "svc2";
 
  private String host = "localhost";
  private static final String SCREEN_CAPTURE__URL = "/deskshare/tunnel/screenCapture";
  private URL url;
  private URLConnection conn;
  private String room;
  private Dimension screenDim;
  private Dimension blockDim;
  private boolean useSVC2;
  private final NextBlockRetriever retriever;
  private volatile boolean processBlocks = false;
  private final int id;
  private NetworkStreamListener listener;
  private final SequenceNumberGenerator seqNumGenerator;
 
  public NetworkHttpStreamSender(int id, NextBlockRetriever retriever, String room,
                  Dimension screenDim, Dimension blockDim, SequenceNumberGenerator seqNumGenerator, boolean useSVC2) {
    this.id = id;
    this.retriever = retriever;
    this.room = room;
    this.screenDim = screenDim;
    this.blockDim = blockDim;
    this.seqNumGenerator = seqNumGenerator;
    this.useSVC2 = useSVC2;
  }
 
  public void addListener(NetworkStreamListener listener) {
    this.listener = listener;
  }
 
  private void notifyNetworkStreamListener(ExitCode reason) {
    if (listener != null) listener.networkException(id,reason);
  }
 
  public void connect(String host) throws ConnectionException {
    this.host = host;
    System.out.println("Starting NetworkHttpStreamSender to " + host);
    openConnection();
  }

  private void openConnection() throws ConnectionException {
    /**
     * Need to re-establish connection each time, otherwise,
     * we get java.net.ProtocolException: Cannot write output after reading input.
     *
     * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4382944
     *
     */       
    long start = System.currentTimeMillis();
    try {     
      url = new URL("http://" + host + SCREEN_CAPTURE__URL);
      conn = url.openConnection();
    } catch (MalformedURLException e) {
      e.printStackTrace();
      throw new ConnectionException("MalformedURLException " + url.toString());
    } catch (IOException e) {
      e.printStackTrace();
      throw new ConnectionException("IOException while connecting to " + url.toString());
    }
    long end = System.currentTimeMillis();
    System.out.println("Http[" + id + "] Open connection took [" + (end-start) + " ms]");
  }
 
  public void sendStartStreamMessage() {
    try {
      System.out.println("Http[" + id + "] Open connection. In sendStartStreamMessage");
      openConnection();
      sendCaptureStartEvent(screenDim, blockDim);
    } catch (ConnectionException e) {
      e.printStackTrace();
      notifyNetworkStreamListener(ExitCode.DESKSHARE_SERVICE_UNAVAILABLE);
    }
  }

  private void sendCaptureStartEvent(Dimension screen, Dimension block) throws ConnectionException {
    ClientHttpRequest chr;
    try {
      chr = new ClientHttpRequest(conn);
      chr.setParameter(ROOM, room);     
      chr.setParameter(SEQ_NUM, seqNumGenerator.getNext());
      String screenInfo = Integer.toString(screen.getWidth()) + "x" + Integer.toString(screen.getHeight());
      chr.setParameter(SCREEN, screenInfo);     
      String blockInfo = Integer.toString(block.getWidth()) + "x" + Integer.toString(block.getHeight());
      chr.setParameter(BLOCK, blockInfo);
      chr.setParameter(EVENT, CaptureEvents.CAPTURE_START.getEvent());
      chr.setParameter(USE_SVC2, Boolean.toString(useSVC2));
      chr.post();
    } catch (IOException e) {
      e.printStackTrace();
      throw new ConnectionException("IOException while sending capture start event.");
    }

  }
 
  public void disconnect() throws ConnectionException {
    try {
      System.out.println("Http[" + id + "] Open connection. In disconnect");
      openConnection();
      sendCaptureEndEvent();
    } catch (ConnectionException e) {
      e.printStackTrace();
      notifyNetworkStreamListener(ExitCode.DESKSHARE_SERVICE_UNAVAILABLE);
      throw e;     
    } finally {
      processBlocks = false;
    }
  }

  private void sendCaptureEndEvent() throws ConnectionException {
    ClientHttpRequest chr;
    try {
      chr = new ClientHttpRequest(conn);
      chr.setParameter(ROOM, room);
      chr.setParameter(SEQ_NUM, seqNumGenerator.getNext());
      chr.setParameter(EVENT, CaptureEvents.CAPTURE_END.getEvent());
      chr.post();
    } catch (IOException e) {
      e.printStackTrace();
      throw new ConnectionException("IOException while sending capture end event.");
    }
  }

  private void processNextMessageToSend(Message message) {

    if (message.getMessageType() == Message.MessageType.BLOCK) {

      long start = System.currentTimeMillis();
      Integer[] changedBlocks = ((BlockMessage) message).getBlocks();
      String blockSize = "Http[" + id + "] Block length [";
      String encodeTime = "Http[" + id + "]Encode times [";
      long encStart = 0;
      long encEnd = 0;
      int totalBytes = 0;
      long totalMillis = 0;

      ClientHttpRequest chr;

      try {

        // Open a connection to the web server and create a request that has
        // the room and event type.
        System.out.println(getTimeStamp() + " Http[" + id + "] Open connection. In sendBlockData");
        openConnection();
        chr = new ClientHttpRequest(conn);
        chr.setParameter(ROOM, room);
        chr.setParameter(EVENT, CaptureEvents.CAPTURE_UPDATE.getEvent());

        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // For each changed block, append an uploaded-file entry to the form data.
        // The file name contains the block info.  The file name has this format:
        // "blockgroup_<seqnum>_<position>".  The original filename is just set to
        // "block<i>".
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        for (int i = 0; i < changedBlocks.length; i++)
        { // append each changed-block to the form

          EncodedBlockData block = retriever.getBlockToSend((Integer) changedBlocks[i]);
          String changed_blocks_upload_filename =
                  BLOCKGROUP + "_" + seqNumGenerator.getNext() + "_" + block.getPosition();
         
          chr.setParameter(changed_blocks_upload_filename, "block"+i, new ByteArrayInputStream(block.getVideoData()));

        } // append each changed-block to the form

        // Post the multi-part form to the server
        chr.post();
        HttpURLConnection httpConnection = (HttpURLConnection) chr.connection;
        int status = httpConnection.getResponseCode();
       
        System.out.println("******* POST status = [" + status + "] ***************");
       
        System.out.println(blockSize + "] total=" + totalBytes + " bytes");
        System.out.println(encodeTime + "] total=" + totalMillis + " ms");
        for (int i = 0; i < changedBlocks.length; i++) {
          retriever.blockSent((Integer) changedBlocks[i]);
        }
        long end = System.currentTimeMillis();
        System.out.println("[HTTP " + id + "] Sending " + changedBlocks.length + " blocks took " + (end - start) + " millis");

      } catch (IOException e) {
        e.printStackTrace();
      } catch (ConnectionException e) {
        System.out.println("ERROR: Failed to send block data.");
      }

      }
      else if (message.getMessageType() == Message.MessageType.CURSOR)
      {

        CursorMessage msg = (CursorMessage) message;

        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        // If the mouse has changed location from the previous time sent,
        // then send its new location.
        //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        if (!msg.getMouseLocation().equals(previousMouseLocation))
        {
           System.out.println("SEND MOUSE: old=" + previousMouseLocation + " new=" + msg.getMouseLocation());
           previousMouseLocation = msg.getMouseLocation();
           sendCursor(previousMouseLocation, msg.getRoom());
        }

    }



  }

  private void processNextMessageToSend_OLD(Message message) {
    if (message.getMessageType() == Message.MessageType.BLOCK) { 
      long start = System.currentTimeMillis();
      Integer[] changedBlocks = ((BlockMessage)message).getBlocks();
      String blockSize = "Http[" + id + "] Block length [";
      String encodeTime = "Http[" + id + "]Encode times [";
      long encStart = 0;
      long encEnd = 0;
      int totalBytes = 0;
      long totalMillis = 0;
      for (int i = 0; i < changedBlocks.length; i++) {
        encStart = System.currentTimeMillis();
        EncodedBlockData block = retriever.getBlockToSend((Integer)changedBlocks[i]);
        totalBytes += block.getVideoData().length;
        blockSize += block.getVideoData().length + ",";
        encEnd = System.currentTimeMillis();
        totalMillis += (encEnd - encStart);
        encodeTime += (encEnd - encStart) + ",";
        BlockVideoData  bv = new BlockVideoData(room, block.getPosition(), block.getVideoData(), false /* should remove later */)
        sendBlockData(bv);
      }
      System.out.println(blockSize + "] total=" + totalBytes + " bytes");
      System.out.println(encodeTime + "] total=" + totalMillis + " ms");
      for (int i = 0; i< changedBlocks.length; i++) {
        retriever.blockSent((Integer)changedBlocks[i]);
      }
      long end = System.currentTimeMillis();
      System.out.println("[HTTP " + id + "] Sending " + changedBlocks.length + " blocks took " + (end - start) + " millis");
    } else if (message.getMessageType() == Message.MessageType.CURSOR) {
      CursorMessage msg = (CursorMessage)message;
      sendCursor(msg.getMouseLocation(), msg.getRoom());
    }
  }

   // NEW
   public void stopProcessingBlocks() { processBlocks = false; }


  public void run() {
    processBlocks = true;
   
    while (processBlocks) {
      Message message;
      try {
        message = retriever.getNextMessageToSend();
        processNextMessageToSend(message);
      } catch (InterruptedException e) {
        e.printStackTrace();
        notifyNetworkStreamListener(ExitCode.DESKSHARE_SERVICE_UNAVAILABLE);
        processBlocks = false;
      }               
    }
  }
 
  private void sendCursor(Point mouseLoc, String room) {
    ClientHttpRequest chr;
    try {
      System.out.println("Http[" + id + "] Open connection. In sendCursor");
      openConnection();
      chr = new ClientHttpRequest(conn);
      chr.setParameter(ROOM, room);
      chr.setParameter(SEQ_NUM, seqNumGenerator.getNext());
      chr.setParameter(EVENT, CaptureEvents.MOUSE_LOCATION_EVENT.getEvent());
      chr.setParameter(MOUSEX, mouseLoc.x);
      chr.setParameter(MOUSEY, mouseLoc.y);
      chr.post();   
      } catch (IOException e) {
        e.printStackTrace();
      } catch (ConnectionException e) {
        System.out.println("ERROR: Failed to send block data.");
      }
  }

        private String getTimeStamp()
        {
         SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");//dd/MM/yyyy
    Date now = new Date();
    String strDate = sdfDate.format(now);
    return strDate;
        }
 
  private void sendBlockData(BlockVideoData blockData) {
    long start = System.currentTimeMillis();
      ClientHttpRequest chr;
    try {
      System.out.println(getTimeStamp()+ " Http[" + id + "] Open connection. In sendBlockData");
      openConnection();
      chr = new ClientHttpRequest(conn);
        chr.setParameter(ROOM, blockData.getRoom());
        chr.setParameter(SEQ_NUM, seqNumGenerator.getNext());
        chr.setParameter(POSITION, blockData.getPosition());
        chr.setParameter(KEYFRAME, blockData.isKeyFrame());
        chr.setParameter(EVENT, CaptureEvents.CAPTURE_UPDATE.getEvent());
      ByteArrayInputStream block = new ByteArrayInputStream(blockData.getVideoData());       
      chr.setParameter(BLOCKDATA, "block", block);
      chr.post();
               //         try {
               //         Thread.sleep(1000);
               //         }
               //         catch (InterruptedException e)
               //         { }
   
    } catch (IOException e) {
      e.printStackTrace();
    } catch (ConnectionException e) {
      System.out.println("ERROR: Failed to send block data.");
    }
    long end = System.currentTimeMillis();
    System.out.println(getTimeStamp() + " [HTTP " + id + "] Sending " + blockData.getVideoData().length + " bytes took " + (end - start) + " ms");
  }   
}
TOP

Related Classes of org.bigbluebutton.deskshare.client.net.NetworkHttpStreamSender

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.