示例#1
0
  @Override
  public void messageReceived(Object in, IoSession session) throws Exception {
    RTMPConnection conn = (RTMPConnection) session.getAttribute(RTMPConnection.RTMP_CONNECTION_KEY);
    RTMP state = (RTMP) session.getAttribute(ProtocolState.SESSION_KEY);
    IRTMPEvent message = null;
    final Packet packet = (Packet) in;
    message = packet.getMessage();
    final Header header = packet.getHeader();
    final Channel channel = conn.getChannel(header.getChannelId());

    // Increase number of received messages
    conn.messageReceived();

    if (header.getDataType() == TYPE_BYTES_READ) {
      // TODO need to sync the bytes read on edge and origin
      onStreamBytesRead(conn, channel, header, (BytesRead) message);
    }

    if (header.getDataType() == TYPE_INVOKE) {
      final IServiceCall call = ((Invoke) message).getCall();
      final String action = call.getServiceMethodName();
      if (call.getServiceName() == null
          && !conn.isConnected()
          && StreamAction.valueOf(action).equals(StreamAction.CONNECT)) {
        handleConnect(conn, channel, header, (Invoke) message, (RTMP) state);
        return;
      }
    }

    switch (header.getDataType()) {
      case TYPE_CHUNK_SIZE:
      case TYPE_INVOKE:
      case TYPE_FLEX_MESSAGE:
      case TYPE_NOTIFY:
      case TYPE_AUDIO_DATA:
      case TYPE_VIDEO_DATA:
      case TYPE_FLEX_SHARED_OBJECT:
      case TYPE_FLEX_STREAM_SEND:
      case TYPE_SHARED_OBJECT:
      case TYPE_BYTES_READ:
        forwardPacket(conn, packet);
        break;
      case TYPE_PING:
        onPing(conn, channel, header, (Ping) message);
        break;

      default:
        if (log.isDebugEnabled()) {
          log.debug("Unknown type: {}", header.getDataType());
        }
    }
    if (message instanceof Unknown) {
      log.info(message.toString());
    }
    if (message != null) {
      message.release();
    }
  }
示例#2
0
 /**
  * Mark message as sent.
  *
  * @param message Message to mark
  */
 public void messageSent(Packet message) {
   if (message.getMessage() instanceof VideoData) {
     int streamId = message.getHeader().getStreamId();
     AtomicInteger pending = pendingVideos.get(streamId);
     if (pending != null) {
       pending.decrementAndGet();
     }
   }
   writtenMessages.incrementAndGet();
 }
示例#3
0
 /**
  * Mark message as being written.
  *
  * @param message Message to mark
  */
 protected void writingMessage(Packet message) {
   if (message.getMessage() instanceof VideoData) {
     int streamId = message.getHeader().getStreamId();
     final AtomicInteger value = new AtomicInteger();
     AtomicInteger old = pendingVideos.putIfAbsent(streamId, value);
     if (old == null) {
       old = value;
     }
     old.incrementAndGet();
   }
 }
示例#4
0
 /** Pass through all Ping events to origin except ping/pong */
 protected void onPing(RTMPConnection conn, Channel channel, Header source, Ping ping) {
   switch (ping.getEventType()) {
     case Ping.PONG_SERVER:
       // This is the response to an IConnection.ping request
       conn.pingReceived(ping);
       break;
     default:
       // forward other to origin
       Packet p = new Packet(source);
       p.setMessage(ping);
       forwardPacket(conn, p);
   }
 }
示例#5
0
  protected void handleConnect(
      RTMPConnection conn, Channel channel, Header header, Invoke invoke, RTMP rtmp) {
    final IPendingServiceCall call = invoke.getCall();
    // Get parameters passed from client to NetConnection#connection
    final Map<String, Object> params = invoke.getConnectionParams();

    // Get hostname
    String host = getHostname((String) params.get("tcUrl"));

    // App name as path, but without query string if there is one
    String path = (String) params.get("app");
    if (path.indexOf("?") != -1) {
      int idx = path.indexOf("?");
      params.put("queryString", path.substring(idx));
      path = path.substring(0, idx);
    }
    params.put("path", path);

    final String sessionId = null;

    conn.setup(host, path, sessionId, params);

    // check the security constraints
    // send back "ConnectionRejected" if fails.
    if (!checkPermission(conn)) {
      call.setStatus(Call.STATUS_ACCESS_DENIED);
      call.setResult(getStatus(NC_CONNECT_REJECTED));
      Invoke reply = new Invoke();
      reply.setCall(call);
      reply.setInvokeId(invoke.getInvokeId());
      channel.write(reply);
      conn.close();
    } else {
      synchronized (rtmp) {
        // connect the origin
        sendConnectMessage(conn);
        rtmp.setState(RTMP.STATE_EDGE_CONNECT_ORIGIN_SENT);
        Packet packet = new Packet(header);
        packet.setMessage(invoke);
        forwardPacket(conn, packet);
        rtmp.setState(RTMP.STATE_ORIGIN_CONNECT_FORWARDED);
        // Evaluate request for AMF3 encoding
        if (Integer.valueOf(3).equals(params.get("objectEncoding"))) {
          rtmp.setEncoding(Encoding.AMF3);
        }
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public void messageReceived(IoSession session, Object in) {
    if (log.isDebugEnabled()) {
      if (in instanceof IoBuffer) {
        log.debug("Handskake");
        return;
      }
      try {
        final Packet packet = (Packet) in;
        final Object message = packet.getMessage();
        final Header source = packet.getHeader();

        log.debug("{}", source);
        log.debug("{}", message);
      } catch (RuntimeException e) {
        log.error("Exception", e);
      }
    }
  }
 /** {@inheritDoc} */
 public void messageReceived(RTMPConnection conn, Packet packet) throws Exception {
   log.trace("messageReceived connection: {}", conn.getSessionId());
   if (conn != null) {
     IRTMPEvent message = null;
     try {
       message = packet.getMessage();
       final Header header = packet.getHeader();
       final Number streamId = header.getStreamId();
       final Channel channel = conn.getChannel(header.getChannelId());
       final IClientStream stream = conn.getStreamById(streamId);
       if (log.isTraceEnabled()) {
         log.trace("Message received - header: {}", header);
       }
       // set stream id on the connection
       conn.setStreamId(streamId);
       // increase number of received messages
       conn.messageReceived();
       // set the source of the message
       message.setSource(conn);
       // process based on data type
       final byte headerDataType = header.getDataType();
       if (log.isTraceEnabled()) {
         log.trace("Header / message data type: {}", headerDataType);
       }
       switch (headerDataType) {
         case TYPE_AGGREGATE:
           log.debug(
               "Aggregate type data - header timer: {} size: {}",
               header.getTimer(),
               header.getSize());
         case TYPE_AUDIO_DATA:
         case TYPE_VIDEO_DATA:
           // mark the event as from a live source
           // log.trace("Marking message as originating from a Live source");
           message.setSourceType(Constants.SOURCE_TYPE_LIVE);
           // NOTE: If we respond to "publish" with "NetStream.Publish.BadName",
           // the client sends a few stream packets before stopping. We need to ignore them
           if (stream != null) {
             ((IEventDispatcher) stream).dispatchEvent(message);
           }
           break;
         case TYPE_FLEX_SHARED_OBJECT:
         case TYPE_SHARED_OBJECT:
           onSharedObject(conn, channel, header, (SharedObjectMessage) message);
           break;
         case TYPE_INVOKE:
         case TYPE_FLEX_MESSAGE:
           onCommand(conn, channel, header, (Invoke) message);
           IPendingServiceCall call = ((Invoke) message).getCall();
           if (message.getHeader().getStreamId().intValue() != 0
               && call.getServiceName() == null
               && StreamAction.PUBLISH.equals(call.getServiceMethodName())) {
             if (stream != null) {
               // Only dispatch if stream really was created
               ((IEventDispatcher) stream).dispatchEvent(message);
             }
           }
           break;
         case TYPE_NOTIFY: // like an invoke, but does not return
           // anything and has a invoke / transaction
           // id of 0
         case TYPE_FLEX_STREAM_SEND:
           if (((Notify) message).getData() != null && stream != null) {
             // Stream metadata
             ((IEventDispatcher) stream).dispatchEvent(message);
           } else {
             onCommand(conn, channel, header, (Notify) message);
           }
           break;
         case TYPE_PING:
           onPing(conn, channel, header, (Ping) message);
           break;
         case TYPE_BYTES_READ:
           onStreamBytesRead(conn, channel, header, (BytesRead) message);
           break;
         case TYPE_CHUNK_SIZE:
           onChunkSize(conn, channel, header, (ChunkSize) message);
           break;
         case Constants.TYPE_CLIENT_BANDWIDTH: // onBWDone / peer bw
           log.debug("Client bandwidth: {}", message);
           onClientBandwidth(conn, channel, (ClientBW) message);
           break;
         case Constants.TYPE_SERVER_BANDWIDTH: // window ack size
           log.debug("Server bandwidth: {}", message);
           onServerBandwidth(conn, channel, (ServerBW) message);
           break;
         default:
           log.debug("Unknown type: {}", header.getDataType());
       }
       if (message instanceof Unknown) {
         log.info("Message type unknown: {}", message);
       }
     } catch (Throwable t) {
       log.error("Exception", t);
     }
     // XXX this may be causing 'missing' data if previous methods are
     // not making copies before buffering etc..
     if (message != null) {
       message.release();
     }
   }
 }
示例#8
0
 /**
  * Releases a packet.
  *
  * @param packet Packet to release
  */
 private void freePacket(Packet packet) {
   if (packet != null && packet.getData() != null) {
     packet.clearData();
   }
 }