/*
* myLib - https://github.com/taktod/myLib
* Copyright (c) 2014 ttProject. All rights reserved.
*
* Licensed under The MIT license.
*/
package com.ttProject.rtmp.netty;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import com.ttProject.rtmp.command.CommandType;
import com.ttProject.rtmp.message.IRtmpMessage;
import com.ttProject.rtmp.message.type.Acknowledgement;
import com.ttProject.rtmp.message.type.Amf0Command;
import com.ttProject.rtmp.message.type.SetPeerBandwidth;
import com.ttProject.rtmp.message.type.UserControlMessage;
import com.ttProject.rtmp.message.type.WindowAcknowledgementSize;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
/**
* ClientHandler
* @author taktod
*/
public class ClientHandler extends ChannelInboundHandlerAdapter {
private Logger logger = Logger.getLogger(ClientHandler.class);
private int bytesReadWindow = 2500000;
@SuppressWarnings("unused")
private int bytesWrittenWindow = 2500000;
// private int transactionId = 2; // for unique transactionId, increment to use.
private Map<Integer, CommandType> transactionMap = new HashMap<Integer, CommandType>();
private long bytesRead = 0;
private long bytesReadAcked = 0;
/**
* {@inheritDoc}
*/
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
if(!(msg instanceof IRtmpMessage)) {
logger.info("not IRtmpMessage object, invalid.");
return;
}
IRtmpMessage message = (IRtmpMessage)msg;
bytesRead += message.getHeader().getSize();
if(bytesRead - bytesReadAcked >= bytesReadWindow) {
// need to send acknowledgement for server.
Acknowledgement acknowledgement = new Acknowledgement();
acknowledgement.setSize((int)bytesRead);
ctx.writeAndFlush(acknowledgement);
bytesReadAcked = bytesRead;
}
switch(message.getHeader().getMessageType()) {
case ABORT_MESSAGE:
case ACKNOWLEDGEMENT:
case AGGREGATE_MESSAGE:
break;
case AMF0_COMMAND:
Amf0Command amf0Command = (Amf0Command)message;
CommandType type = amf0Command.getCommandType();
switch(type) {
case Result:
CommandType resType = transactionMap.get(amf0Command.getTransactionId());
if(resType == null) {
super.channelRead(ctx, msg);
return;
}
switch(resType) {
default:
break;
}
break;
default:
break;
}
break;
case AMF0_DATA_MESSAGE:
case AMF0_SHARED_OBJECT_MESSAGE:
case AMF3_COMMAND:
case AMF3_DATA_MESSAGE:
case AMF3_SHARED_OBJECT_MESSAGE:
case AUDIO_MESSAGE:
break;
case SET_CHUNK_SIZE:
// nothing to do, already done with readDecoder.
break;
case USER_CONTROL_MESSAGE:
UserControlMessage userControlMessage = (UserControlMessage)message;
// logger.info(userControlMessage.getType());
switch(userControlMessage.getType()) {
case BUFFER_EMPTY:
// logger.info("buffer empty for stream.");
break;
case BUFFER_FULL:
// logger.info("buffer full for stream.");
break;
case CLIENT_BUFFER_LENGTH:
break;
case PING:
// reply pong for ping.
int time = userControlMessage.getTime();
UserControlMessage pong = new UserControlMessage();
pong.setType(UserControlMessage.Type.PONG);
pong.setTime(time);
ctx.writeAndFlush(pong);
break;
case PONG:
break;
case PING_SWF_VERIFICATION:
case PONG_SWF_VERIFICATION:
break;
case RECORDED_STREAM:
case STREAM_BEGIN:
case STREAM_DRY:
case STREAM_EOF:
break;
}
break;
case VIDEO_MESSAGE:
break;
case WINDOW_ACKNOWLEDGEMENT_SIZE:
WindowAcknowledgementSize windowAcknowledgementSize = (WindowAcknowledgementSize)message;
bytesReadWindow = windowAcknowledgementSize.getAcknowledgementSize();
break;
case SET_PEER_BANDWIDTH:
SetPeerBandwidth setPeerBandwidth = (SetPeerBandwidth)message;
bytesWrittenWindow = setPeerBandwidth.getAcknowledgeWindowSize();
break;
default:
break;
}
super.channelRead(ctx, msg);
}
}