Package cz.woitee.websockets.streams

Source Code of cz.woitee.websockets.streams.ServersideWebSocketInputStream

package cz.woitee.websockets.streams;

import java.io.*;
import java.net.Socket;

import cz.woitee.websockets.WebSocketFrame;
import cz.woitee.websockets.WebSocketException;

public class ServersideWebSocketInputStream extends FilterInputStream {

  protected Socket socket;
 
  public ServersideWebSocketInputStream(Socket socket) throws IOException {
    super(socket.getInputStream());
    this.socket = socket;
  }
 
  private byte[] payload = new byte[0];
  private int ptr = 0;
 
  /**
   * Reads next usable WebSocket frame and saves the bytes in the payload variable.
   * Ping frames will be automatically responded to along the way and not returned.
   * Masking on client messages is required, so non-masked frames will cause a
   * WebSocketException.
   * Close frames will cause a WebSocketException.
   *
   * @return Bytes stored in the payload variable, or -1 if no bytes could be read.
   * @throws WebSocketException
   * @throws IOException
   */
  private int readNextFrame() throws WebSocketException, IOException {
    boolean ping;
    WebSocketFrame readResult;
    do {
      readResult = WebSocketFrame.readFrame(in);
      if (readResult.bytesRead == -1) { return -1; }
      if (readResult.masked == false) {
        throw new WebSocketException("Received an unmasked frame from client.");
      }
      if (readResult.opcode == 0x8) {
        throw new WebSocketException("The opposite side closed the WebSocket connection.");
      }
      ping = readResult.opcode == 0x9;
      if (ping) {
        //automatically form ping response (pong)
        byte[] appData = readResult.bytes;
        socket.getOutputStream().write(
          WebSocketFrame.construct(appData, 0, appData.length, 0xA)
        );
      }
    } while (ping);
   
    //readResult.bytesRead != -1, so the read was succesful
    payload = readResult.bytes;
    ptr = 0;
    return payload.length;
  }
 
  @Override
  public int read() throws IOException {
    while (ptr >= payload.length) {
      if (readNextFrame() == -1) { return -1; }
    }
   
    return payload[ptr++];
  }
 
  @Override
  public int read(byte[] b) throws IOException {
    return read(b, 0, b.length);
  }
 
  @Override
  public int read(byte[] b, int off, int len) throws IOException {
    if (len == 0) { return 0; }
    //try copying at least one byte
    int res = read();
    if (res == -1) { return -1; }
    b[off] = (byte)res;
    //copy as many more as you can without blocking
    int copyPtr = off + 1;
    while((in.available() > 0 || ptr < payload.length) && copyPtr < off+len) {
      if (ptr < payload.length) {
        b[copyPtr++] = payload[ptr++];
      } else {
        if (readNextFrame() == -1) { return -1; }
      }
    }
   
    return copyPtr - off;
  }
}
TOP

Related Classes of cz.woitee.websockets.streams.ServersideWebSocketInputStream

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.