Пример #1
0
  /**
   * @param remote Indicates who "generated" <code>code</code>.<br>
   *     <code>true</code> means that this endpoint received the <code>code</code> from the other
   *     endpoint.<br>
   *     false means this endpoint decided to send the given code,<br>
   *     <code>remote</code> may also be true if this endpoint started the closing handshake since
   *     the other endpoint may not simply echo the <code>code</code> but close the connection the
   *     same time this endpoint does do but with an other <code>code</code>. <br>
   */
  protected synchronized void closeConnection(int code, String message, boolean remote) {
    if (readystate == READYSTATE.CLOSED) {
      return;
    }

    if (key != null) {
      // key.attach( null ); //see issue #114
      key.cancel();
    }
    if (channel != null) {
      try {
        channel.close();
      } catch (IOException e) {
        wsl.onWebsocketError(this, e);
      }
    }
    try {
      this.wsl.onWebsocketClose(this, code, message, remote);
    } catch (RuntimeException e) {
      wsl.onWebsocketError(this, e);
    }
    if (draft != null) draft.reset();
    handshakerequest = null;

    readystate = READYSTATE.CLOSED;
    this.outQueue.clear();
  }
Пример #2
0
 private void open(Handshakedata d) {
   if (DEBUG) System.out.println("open using draft: " + draft.getClass().getSimpleName());
   readystate = READYSTATE.OPEN;
   try {
     wsl.onWebsocketOpen(this, d);
   } catch (RuntimeException e) {
     wsl.onWebsocketError(this, e);
   }
 }
 /** {@inheritDoc} */
 @Override
 public final void onFailure(Throwable t) {
   for (WebSocketListener listener : listeners) {
     if (!ok.get() && webSocket != null) {
       webSocket.addWebSocketListener(listener);
     }
     listener.onError(t);
   }
 }
 /** {@inheritDoc} */
 @Override
 public final void onSuccess(WebSocket webSocket) {
   this.webSocket = webSocket;
   for (WebSocketListener listener : listeners) {
     webSocket.addWebSocketListener(listener);
     listener.onOpen(webSocket);
   }
   ok.set(true);
 }
  /** {@inheritDoc} */
  @Override
  public final WebSocket onCompleted() throws Exception {

    if (status != SWITCHING_PROTOCOLS) {
      IllegalStateException e = new IllegalStateException("Invalid Status Code " + status);
      for (WebSocketListener listener : listeners) {
        listener.onError(e);
      }
      throw e;
    }

    return webSocket;
  }
 /** {@inheritDoc} */
 @Override
 public final void onSuccess(WebSocket webSocket) {
   this.webSocket = webSocket;
   for (WebSocketListener listener : listeners) {
     webSocket.addWebSocketListener(listener);
     listener.onOpen(webSocket);
   }
   if (isNonEmpty(bufferedFrames)) {
     for (Runnable bufferedFrame : bufferedFrames) {
       bufferedFrame.run();
     }
     bufferedFrames = null;
   }
   ok.set(true);
 }
  public final void onClose(WebSocket webSocket, int status, String reasonPhrase) {
    // Connect failure
    if (this.webSocket == null) this.webSocket = webSocket;

    for (WebSocketListener listener : listeners) {
      if (webSocket != null) {
        webSocket.addWebSocketListener(listener);
      }
      listener.onClose(webSocket);
      if (listener instanceof WebSocketCloseCodeReasonListener) {
        WebSocketCloseCodeReasonListener.class
            .cast(listener)
            .onClose(webSocket, status, reasonPhrase);
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public final WebSocket onCompleted() throws Exception {

    if (status != 101) {
      IllegalStateException e = new IllegalStateException("Invalid Status Code " + status);
      for (WebSocketListener listener : listeners) {
        listener.onError(e);
      }
      throw e;
    }

    if (webSocket == null) {
      throw new NullPointerException("webSocket");
    }
    return webSocket;
  }
Пример #9
0
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Request progress bar
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

    setContentView(R.layout.activity_main);

    mAppView = (WebView) findViewById(R.id.webView1);
    mButton1 = (Button) findViewById(R.id.button1);
    mEditText = (EditText) findViewById(R.id.editText1);
    mTimePicker = (TimePicker) findViewById(R.id.timePicker1);
    mSocketSpinner = (Spinner) findViewById(R.id.spinner1);
    mSendTools = (LinearLayout) findViewById(R.id.sendTools);

    mProgresBar = (ProgressBar) findViewById(R.id.progressBar);

    setProgressBarIndeterminateVisibility(true);

    // Add listener for spinner
    addListenerOnSpinnerItemSelection();

    // Choose selected web socket address
    mSelectedSocketPos = mSocketSpinner.getSelectedItemPosition();
    mWebSocketAddress = getResources().getStringArray(R.array.sockets)[mSelectedSocketPos];
    //        webSocketAddress = WEB_SOCKET_ADDRESS;

    // Set web socket address and add listener
    setWebSocket(mWebSocketAddress);

    // connect
    Toast.makeText(getApplicationContext(), "Connecting", Toast.LENGTH_SHORT).show();
    mWebSocketListener.connectTh();
  }
Пример #10
0
  /**
   * Close Web Socket connection, and reconnect if needed
   *
   * @param reconnect - if true reconnect will be performed
   */
  private void closeWebSocket(boolean reconnect) {
    this.mReconnect = reconnect;

    // Disable send button
    setButtonSendEnabledT(false);

    // Close current connection
    mWebSocketListener.close();
  }
Пример #11
0
  protected synchronized void flushAndClose(int code, String message, boolean remote) {
    if (flushandclosestate) {
      return;
    }
    closecode = code;
    closemessage = message;
    closedremotely = remote;

    flushandclosestate = true;

    wsl.onWriteDemand(
        this); // ensures that all outgoing frames are flushed before closing the connection
    try {
      wsl.onWebsocketClosing(this, code, message, remote);
    } catch (RuntimeException e) {
      wsl.onWebsocketError(this, e);
    }
    if (draft != null) draft.reset();
    handshakerequest = null;
  }
Пример #12
0
  public void startHandshake(ClientHandshakeBuilder handshakedata)
      throws InvalidHandshakeException {
    assert (readystate != READYSTATE.CONNECTING) : "shall only be called once";

    // Store the Handshake Request we are about to send
    this.handshakerequest = draft.postProcessHandshakeRequestAsClient(handshakedata);

    // Notify Listener
    try {
      wsl.onWebsocketHandshakeSentAsClient(this, this.handshakerequest);
    } catch (InvalidDataException e) {
      // Stop if the client code throws an exception
      throw new InvalidHandshakeException("Handshake data rejected by client.");
    } catch (RuntimeException e) {
      wsl.onWebsocketError(this, e);
      throw new InvalidHandshakeException("rejected because of" + e);
    }

    // Send
    write(draft.createHandshake(this.handshakerequest, role));
  }
Пример #13
0
 private void close(int code, String message, boolean remote) {
   if (readystate != READYSTATE.CLOSING && readystate != READYSTATE.CLOSED) {
     if (readystate == READYSTATE.OPEN) {
       if (code == CloseFrame.ABNORMAL_CLOSE) {
         assert (remote == false);
         readystate = READYSTATE.CLOSING;
         flushAndClose(code, message, false);
         return;
       }
       if (draft.getCloseHandshakeType() != CloseHandshakeType.NONE) {
         try {
           if (!remote) {
             try {
               wsl.onWebsocketCloseInitiated(this, code, message);
             } catch (RuntimeException e) {
               wsl.onWebsocketError(this, e);
             }
           }
           sendFrame(new CloseFrameBuilder(code, message));
         } catch (InvalidDataException e) {
           wsl.onWebsocketError(this, e);
           flushAndClose(CloseFrame.ABNORMAL_CLOSE, "generated frame is invalid", false);
         }
       }
       flushAndClose(code, message, remote);
     } else if (code == CloseFrame.FLASHPOLICY) {
       assert (remote);
       flushAndClose(CloseFrame.FLASHPOLICY, message, true);
     } else {
       flushAndClose(CloseFrame.NEVER_CONNECTED, message, false);
     }
     if (code == CloseFrame.PROTOCOL_ERROR) // this endpoint found a PROTOCOL_ERROR
     flushAndClose(code, message, remote);
     readystate = READYSTATE.CLOSING;
     tmpHandshakeBytes = null;
     return;
   }
 }
Пример #14
0
  private void write(ByteBuffer buf) {
    if (DEBUG)
      System.out.println(
          "write("
              + buf.remaining()
              + "): {"
              + (buf.remaining() > 1000 ? "too big to display" : new String(buf.array()))
              + "}");

    outQueue.add(buf);
    /*try {
    	outQueue.put( buf );
    } catch ( InterruptedException e ) {
    	write( buf );
    	Thread.currentThread().interrupt(); // keep the interrupted status
    	e.printStackTrace();
    }*/
    wsl.onWriteDemand(this);
  }
Пример #15
0
 /**
  * Button callback function
  *
  * @param v - related Button view
  */
 public void onClickButton1(View v) {
   if (mEditText.getText().length() > 0) {
     mButton1.setEnabled(false);
     mWebSocketListener.send(mEditText.getText().toString());
   }
 }
Пример #16
0
 @Override
 public InetSocketAddress getLocalSocketAddress() {
   return wsl.getLocalSocketAddress(this);
 }
Пример #17
0
 @Override
 public InetSocketAddress getRemoteSocketAddress() {
   return wsl.getRemoteSocketAddress(this);
 }
Пример #18
0
  private void addWebSocketEventListener() {

    mWebSocketListener.addWebSocketEventListener(
        new WebSocketEventListener() {

          public void handleOpenEvent() {
            Log.v("handleOpenEvent", "OPENED");
            String customHtml = "<html><body>Conected</body></html>";
            mAppView.loadData(customHtml, "text/html", "UTF-8"); // only for appView

            if (mSelectedSocketPos == DEFAULT_POS) {
              // editText.setEnabled(false);
              setTonePickerVisibilityT(true);
            } else {
              setSendToolsVisibilityT(true);
              setButtonSendEnabledT(true);
              mEditText.setEnabled(true);
            }
            setProgressBarVisibilityT(false);
          }

          public void handleSendEvent(String newMsg) {
            Log.v("handleOpenEvent", "RECEIVED");
            String customHtml;

            if (mSelectedSocketPos == DEFAULT_POS) { // default socket handle TimePicker
              customHtml = "<html><body>" + newMsg + "<br/>" + mOldMessage + "</body></html>";
              updateTimePickerT(getHourFromString(newMsg), getMinuteFromString(newMsg));
            } else {
              customHtml =
                  "<html><body><font color=\"red\">RESPONSE: </font>"
                      + newMsg
                      + "<br/>"
                      + mOldMessage
                      + "</body></html>";
              setEditTextT("");
              setButtonSendEnabledT(true);
            }

            mAppView.loadData(customHtml, "text/html", "UTF-8");

            if (mSelectedSocketPos != DEFAULT_POS) {
              mOldMessage = newMsg + "<br/>" + mOldMessage; // to store history			
            }
          }

          public void handleCloseEvent() {
            Log.v("handleOpenEvent", "CLOSED");
            // Toast.makeText(getApplicationContext(), "Closed", Toast.LENGTH_SHORT).show();

            if (mReconnect) {
              Toast.makeText(getApplicationContext(), "Reconnecting", Toast.LENGTH_SHORT).show();
              mReconnect = RECONNECT_DEFAULT;

              // Set web socket address and add listener
              setWebSocket(mWebSocketAddress);

              // connect
              mWebSocketListener.connectTh();
            } else {
              // setButtonSendEnabledT(true);			// enable button
            }
          }
        });
  }
Пример #19
0
  private void decodeFrames(ByteBuffer socketBuffer) {

    List<Framedata> frames;
    try {
      frames = draft.translateFrame(socketBuffer);
      for (Framedata f : frames) {
        if (DEBUG) System.out.println("matched frame: " + f);
        Opcode curop = f.getOpcode();
        boolean fin = f.isFin();

        if (curop == Opcode.CLOSING) {
          int code = CloseFrame.NOCODE;
          String reason = "";
          if (f instanceof CloseFrame) {
            CloseFrame cf = (CloseFrame) f;
            code = cf.getCloseCode();
            reason = cf.getMessage();
          }
          if (readystate == READYSTATE.CLOSING) {
            // complete the close handshake by disconnecting
            closeConnection(code, reason, true);
          } else {
            // echo close handshake
            if (draft.getCloseHandshakeType() == CloseHandshakeType.TWOWAY)
              close(code, reason, true);
            else flushAndClose(code, reason, false);
          }
          continue;
        } else if (curop == Opcode.PING) {
          wsl.onWebsocketPing(this, f);
          continue;
        } else if (curop == Opcode.PONG) {
          wsl.onWebsocketPong(this, f);
          continue;
        } else if (!fin || curop == Opcode.CONTINUOUS) {
          if (curop != Opcode.CONTINUOUS) {
            if (current_continuous_frame_opcode != null)
              throw new InvalidDataException(
                  CloseFrame.PROTOCOL_ERROR, "Previous continuous frame sequence not completed.");
            current_continuous_frame_opcode = curop;
          } else if (fin) {
            if (current_continuous_frame_opcode == null)
              throw new InvalidDataException(
                  CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence was not started.");
            current_continuous_frame_opcode = null;
          } else if (current_continuous_frame_opcode == null) {
            throw new InvalidDataException(
                CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence was not started.");
          }
          try {
            wsl.onWebsocketMessageFragment(this, f);
          } catch (RuntimeException e) {
            wsl.onWebsocketError(this, e);
          }

        } else if (current_continuous_frame_opcode != null) {
          throw new InvalidDataException(
              CloseFrame.PROTOCOL_ERROR, "Continuous frame sequence not completed.");
        } else if (curop == Opcode.TEXT) {
          try {
            wsl.onWebsocketMessage(this, Charsetfunctions.stringUtf8(f.getPayloadData()));
          } catch (RuntimeException e) {
            wsl.onWebsocketError(this, e);
          }
        } else if (curop == Opcode.BINARY) {
          try {
            wsl.onWebsocketMessage(this, f.getPayloadData());
          } catch (RuntimeException e) {
            wsl.onWebsocketError(this, e);
          }
        } else {
          throw new InvalidDataException(
              CloseFrame.PROTOCOL_ERROR, "non control or continious frame expected");
        }
      }
    } catch (InvalidDataException e1) {
      wsl.onWebsocketError(this, e1);
      close(e1);
      return;
    }
  }
Пример #20
0
  /**
   * Returns whether the handshake phase has is completed. In case of a broken handshake this will
   * be never the case.
   */
  private boolean decodeHandshake(ByteBuffer socketBufferNew) {
    ByteBuffer socketBuffer;
    if (tmpHandshakeBytes.capacity() == 0) {
      socketBuffer = socketBufferNew;
    } else {
      if (tmpHandshakeBytes.remaining() < socketBufferNew.remaining()) {
        ByteBuffer buf =
            ByteBuffer.allocate(tmpHandshakeBytes.capacity() + socketBufferNew.remaining());
        tmpHandshakeBytes.flip();
        buf.put(tmpHandshakeBytes);
        tmpHandshakeBytes = buf;
      }

      tmpHandshakeBytes.put(socketBufferNew);
      tmpHandshakeBytes.flip();
      socketBuffer = tmpHandshakeBytes;
    }
    socketBuffer.mark();
    try {
      if (draft == null) {
        HandshakeState isflashedgecase = isFlashEdgeCase(socketBuffer);
        if (isflashedgecase == HandshakeState.MATCHED) {
          try {
            write(ByteBuffer.wrap(Charsetfunctions.utf8Bytes(wsl.getFlashPolicy(this))));
            close(CloseFrame.FLASHPOLICY, "");
          } catch (InvalidDataException e) {
            close(
                CloseFrame.ABNORMAL_CLOSE,
                "remote peer closed connection before flashpolicy could be transmitted",
                true);
          }
          return false;
        }
      }
      HandshakeState handshakestate = null;

      try {
        if (role == Role.SERVER) {
          if (draft == null) {
            for (Draft d : knownDrafts) {
              d = d.copyInstance();
              try {
                d.setParseMode(role);
                socketBuffer.reset();
                Handshakedata tmphandshake = d.translateHandshake(socketBuffer);
                if (tmphandshake instanceof ClientHandshake == false) {
                  flushAndClose(CloseFrame.PROTOCOL_ERROR, "wrong http function", false);
                  return false;
                }
                ClientHandshake handshake = (ClientHandshake) tmphandshake;
                handshakestate = d.acceptHandshakeAsServer(handshake);
                if (handshakestate == HandshakeState.MATCHED) {
                  resourceDescriptor = handshake.getResourceDescriptor();
                  ServerHandshakeBuilder response;
                  try {
                    response = wsl.onWebsocketHandshakeReceivedAsServer(this, d, handshake);
                  } catch (InvalidDataException e) {
                    flushAndClose(e.getCloseCode(), e.getMessage(), false);
                    return false;
                  } catch (RuntimeException e) {
                    wsl.onWebsocketError(this, e);
                    flushAndClose(CloseFrame.NEVER_CONNECTED, e.getMessage(), false);
                    return false;
                  }
                  write(
                      d.createHandshake(
                          d.postProcessHandshakeResponseAsServer(handshake, response), role));
                  draft = d;
                  open(handshake);
                  return true;
                }
              } catch (InvalidHandshakeException e) {
                // go on with an other draft
              }
            }
            if (draft == null) {
              close(CloseFrame.PROTOCOL_ERROR, "no draft matches");
            }
            return false;
          } else {
            // special case for multiple step handshakes
            Handshakedata tmphandshake = draft.translateHandshake(socketBuffer);
            if (tmphandshake instanceof ClientHandshake == false) {
              flushAndClose(CloseFrame.PROTOCOL_ERROR, "wrong http function", false);
              return false;
            }
            ClientHandshake handshake = (ClientHandshake) tmphandshake;
            handshakestate = draft.acceptHandshakeAsServer(handshake);

            if (handshakestate == HandshakeState.MATCHED) {
              open(handshake);
              return true;
            } else {
              close(CloseFrame.PROTOCOL_ERROR, "the handshake did finaly not match");
            }
            return false;
          }
        } else if (role == Role.CLIENT) {
          draft.setParseMode(role);
          Handshakedata tmphandshake = draft.translateHandshake(socketBuffer);
          if (tmphandshake instanceof ServerHandshake == false) {
            flushAndClose(CloseFrame.PROTOCOL_ERROR, "wrong http function", false);
            return false;
          }
          ServerHandshake handshake = (ServerHandshake) tmphandshake;
          handshakestate = draft.acceptHandshakeAsClient(handshakerequest, handshake);
          if (handshakestate == HandshakeState.MATCHED) {
            try {
              wsl.onWebsocketHandshakeReceivedAsClient(this, handshakerequest, handshake);
            } catch (InvalidDataException e) {
              flushAndClose(e.getCloseCode(), e.getMessage(), false);
              return false;
            } catch (RuntimeException e) {
              wsl.onWebsocketError(this, e);
              flushAndClose(CloseFrame.NEVER_CONNECTED, e.getMessage(), false);
              return false;
            }
            open(handshake);
            return true;
          } else {
            close(CloseFrame.PROTOCOL_ERROR, "draft " + draft + " refuses handshake");
          }
        }
      } catch (InvalidHandshakeException e) {
        close(e);
      }
    } catch (IncompleteHandshakeException e) {
      if (tmpHandshakeBytes.capacity() == 0) {
        socketBuffer.reset();
        int newsize = e.getPreferedSize();
        if (newsize == 0) {
          newsize = socketBuffer.capacity() + 16;
        } else {
          assert (e.getPreferedSize() >= socketBuffer.remaining());
        }
        tmpHandshakeBytes = ByteBuffer.allocate(newsize);

        tmpHandshakeBytes.put(socketBufferNew);
        // tmpHandshakeBytes.flip();
      } else {
        tmpHandshakeBytes.position(tmpHandshakeBytes.limit());
        tmpHandshakeBytes.limit(tmpHandshakeBytes.capacity());
      }
    }
    return false;
  }