I try to implement a SFTP upload with a progress bar.
Unfortunately the progress bar is not updated...
Here is a part of my code:
public class MainView extends JFrame implements SftpProgressMonitor {
private static final Logger LOG = Logger.getLogger(MainView.class);
private String _source;
private JProgressBar _progressBar;
private JButton _button;
public MainView() {
initComponents();
}
void initComponents() {
_button = new JButton("Send");
_button.addActionListener(new ActionListener() {
// If clicked, send event to controller...
});
_progressBar = new JProgressBar();
// Do init stuff here
// ...
}
#Override
public boolean count(long byteTransfered) {
int transfered = _progressBar.getValue();
transfered += byteTransfered;
_progressBar.setValue(transfered);
return true;
}
#Override
public void end() {
LOG.info("Transfer of "+_source+" finished!");
}
#Override
public void init(int op, String src, String dest, long max) {
_progressBar.setValue(0);
_progressBar.setMinimum(0);
_progressBar.setMaximum((int) max);
_source = src;
}
}
public class Controller {
private final MainView _view;
private final SftpClient _ftp;
private final Server _server;
public Controller() {
_server = new Server("192.168.0.1");
_view = new MainView();
_ftp = new SftpClient(_server);
_view.setVisible(true);
}
public void send() {
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable() {
public void run() {
File testFile = new File("/PathToFile/file.txt");
String remoteDir = "/MyRemoteDir/";
_ftp.put(testFile, remoteDir, testFile.getName(), _view);
}
});
}
public static void main(String[] args) {
Controller controller = new Controller();
}
}
public class SftpClient {
private static final Logger LOG = Logger.getLogger(SftpClient.class);
/** Connection port number */
public static final int PORT = 22;
/** SECURED protocol name */
public static final String PROTOCOL = "sftp";
/** Connection time out in milliseconds */
public static final int TIME_OUT = 3000;
private Server _server;
/** This class serves as a central configuration point, and as a factory for Session objects configured with these settings */
private JSch _client;
/** A session represents a connection to a SSH server */
private Session _session;
/** Channel connected to a SECURED server (as a subsystem of the SSH server) */
private ChannelSftp _channelSftp;
/**
* Value returned by the last executed command.
*/
private int _exitValue;
public SftpClient(Server server) {
_client = new JSch();
_server = server;
}
protected void connect() throws AuthenticationException, Exception {
try {
if (_client == null) {
_client = new JSch();
}
if (_session == null) {
_session = _client.getSession(_server.getLogin(), _server.getAddress(), PORT);
_session.setConfig("StrictHostKeyChecking", "no");
_session.setPassword(_server.getPassword());
if (LOG.isDebugEnabled()) {
LOG.debug("Connecting to "+_server.getAddress()+" with login "+_server.getLogin()+"...");
}
}
if (!_session.isConnected()) {
_session.connect(TIME_OUT);
}
if(_channelSftp == null || _channelSftp.isConnected() == false) {
Channel c = _session.openChannel(PROTOCOL);
c.connect();
// disconnect previous channel if it has not been killed properly
if (_channelSftp != null && _channelSftp.isConnected()) {
_channelSftp.disconnect();
}
_channelSftp = (ChannelSftp) c;
}
if (LOG.isInfoEnabled()) {
LOG.info("Connected to "+_server.getAddress()+" with login "+_server.getLogin());
}
} catch(JSchException e) {
if ("Auth fail".equals(e.getMessage())) {
throw new AuthenticationException(e);
} else {
throw new Exception(e);
}
}
}
protected void connect(String path) throws AuthenticationException, Exception {
connect();
if (_channelSftp != null && _channelSftp.isConnected()) {
_channelSftp.cd(path);
}
}
#Override
public void disconnect() {
if (_channelSftp != null && _channelSftp.isConnected()) {
_channelSftp.disconnect();
_channelSftp.exit();
}
if (_session != null && _session.isConnected()) {
_session.disconnect();
if (LOG.isInfoEnabled()) {
LOG.info("SECURED FTP disconnected");
}
}
}
#Override
public void put(File localFile, String destPath, SftpProgressMonitor monitor) throws Exception {
put(localFile, destPath, localFile.getName(), monitor);
}
#Override
public void put(File localFile, String destPath, String remoteFileName, SftpProgressMonitor monitor) throws Exception {
if (LOG.isInfoEnabled()) {
LOG.info("Send file "+localFile+" to "+_server+" in "+destPath);
}
if (localFile == null) {
_exitValue = -1;
LOG.error("The given local file is null. Aborting tranfer.");
return;
}
if (!localFile.exists()) {
_exitValue = -1;
LOG.error("'"+localFile+"' doesn't exist. Aborting tranfer.");
return;
}
if(!localFile.canRead()) {
_exitValue = -1;
LOG.error("Cannot read '"+localFile+"'. Aborting tranfer.");
return;
}
final InputStream input = new BufferedInputStream(new FileInputStream(localFile));
if (input == null || input.available() <= 0) {
_exitValue = -1;
LOG.error("Cannot read file "+localFile);
return;
}
try {
connect(destPath);
_channelSftp.put(input, remoteFileName, monitor);
_exitValue = _channelSftp.getExitStatus();
} catch(SftpException e){
throw new IOException(e);
} finally {
if (_channelSftp != null && _channelSftp.isConnected()) {
_channelSftp.disconnect();
_channelSftp.exit();
}
IOUtils.closeQuietly(input);
}
}
}
The count() method is never called. And the source and destination strings of the init contain both -. Am I doing it wrong?
I've changed my code and it works now. I don't use put(InputStream src, String dst, int mode) anymore but put(String src, String dst, SftpProgressMonitor monitor).
I've also implemented a DefaultBoundedRangeModel class. It modifies directly the JProgressBar and it is more interesting for me because I have several files to transfer.
public class ProgressModel extends DefaultBoundedRangeModel implements SftpProgressMonitor {
/** Logger */
private static Logger LOG = Logger.getLogger(ProgressModel.class);
private String _fileBeingTransfered;
/**
* Constructs the model.
*/
public ProgressModel() {
_fileBeingTransfered = "";
}
#Override
public boolean count(long count) {
int value = (int) (getValue() + count);
setValue(value);
fireStateChanged();
if(value < getMaximum()) {
return true;
} else {
return false;
}
}
#Override
public void end() {
LOG.info(_fileBeingTransfered+" transfert finished.");
if(getValue() == getMaximum()) {
LOG.info("All transfers are finished!");
}
}
#Override
public void init(int op, String src, String dest, long max) {
LOG.info("Transfering "+src+" to "+dest+" | size: "+max);
_fileBeingTransfered = src;
}
}
I don't know what caused my problem. Maybe it was the put method.
In order to get updates you have to send reference to monitor to FTP client. And you do this:
_ftp.put(testFile, remoteDir, testFile.getName(), _view);
However what _view is? It is a private final field of class Controller that is never initialized. Therefore it is null. You implemented your callback method count() into class MainView but do not send reference to it to the FTP client. I do not know where do you create instance of Controller but you should pass reference to instance of MainView to it.
Related
I am using WebSocketClient class to get the data from websocket in my android app but when anything change in Internet connection ( Disconnect from Internet ) it gives the following error in WebSocketClient.java file
USER_COMMENT=null
ANDROID_VERSION=10
APP_VERSION_NAME=0.0.1
BRAND=google
PHONE_MODEL=Android SDK built for x86_64
CUSTOM_DATA=
STACK_TRACE=java.lang.AssertionError
at org.java_websocket.client.WebSocketClient.run(WebSocketClient.java:190)
at java.lang.Thread.run(Thread.java:919)
But the WebSocketClient.java is read only file it is coming from java-websocket-1.3.0.jar file
WebSocketClient.java
package org.java_websocket.client;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.nio.channels.CancelledKeyException;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.NotYetConnectedException;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.CountDownLatch;
import org.java_websocket.SocketChannelIOHelper;
import org.java_websocket.WebSocket;
import org.java_websocket.WebSocketAdapter;
import org.java_websocket.WebSocketFactory;
import org.java_websocket.WebSocketImpl;
import org.java_websocket.WrappedByteChannel;
import org.java_websocket.WebSocket.READYSTATE;
import org.java_websocket.drafts.Draft;
import org.java_websocket.drafts.Draft_10;
import org.java_websocket.exceptions.InvalidHandshakeException;
import org.java_websocket.handshake.HandshakeImpl1Client;
import org.java_websocket.handshake.Handshakedata;
import org.java_websocket.handshake.ServerHandshake;
public abstract class WebSocketClient extends WebSocketAdapter implements Runnable {
protected URI uri;
private WebSocketImpl conn;
private SocketChannel channel;
private ByteChannel wrappedchannel;
private Thread writethread;
private Thread readthread;
private Draft draft;
private Map<String, String> headers;
private CountDownLatch connectLatch;
private CountDownLatch closeLatch;
private int timeout;
private WebSocketClient.WebSocketClientFactory wsfactory;
private InetSocketAddress proxyAddress;
public WebSocketClient(URI serverURI) {
this(serverURI, new Draft_10());
}
public WebSocketClient(URI serverUri, Draft draft) {
this(serverUri, draft, (Map)null, 0);
}
public WebSocketClient(URI serverUri, Draft draft, Map<String, String> headers, int connecttimeout) {
this.uri = null;
this.conn = null;
this.channel = null;
this.wrappedchannel = null;
this.connectLatch = new CountDownLatch(1);
this.closeLatch = new CountDownLatch(1);
this.timeout = 0;
this.wsfactory = new DefaultWebSocketClientFactory(this);
this.proxyAddress = null;
if (serverUri == null) {
throw new IllegalArgumentException();
} else if (draft == null) {
throw new IllegalArgumentException("null as draft is permitted for `WebSocketServer` only!");
} else {
this.uri = serverUri;
this.draft = draft;
this.headers = headers;
this.timeout = connecttimeout;
try {
this.channel = SelectorProvider.provider().openSocketChannel();
this.channel.configureBlocking(true);
} catch (IOException var6) {
this.channel = null;
this.onWebsocketError((WebSocket)null, var6);
}
if (this.channel == null) {
this.conn = (WebSocketImpl)this.wsfactory.createWebSocket(this, draft, (Socket)null);
this.conn.close(-1, "Failed to create or configure SocketChannel.");
} else {
this.conn = (WebSocketImpl)this.wsfactory.createWebSocket(this, draft, this.channel.socket());
}
}
}
public URI getURI() {
return this.uri;
}
public Draft getDraft() {
return this.draft;
}
public void connect() {
if (this.writethread != null) {
throw new IllegalStateException("WebSocketClient objects are not reuseable");
} else {
this.writethread = new Thread(this);
this.writethread.start();
}
}
public boolean connectBlocking() throws InterruptedException {
this.connect();
this.connectLatch.await();
return this.conn.isOpen();
}
public void close() {
if (this.writethread != null) {
this.conn.close(1000);
}
}
public void closeBlocking() throws InterruptedException {
this.close();
this.closeLatch.await();
}
public void send(String text) throws NotYetConnectedException {
this.conn.send(text);
}
public void send(byte[] data) throws NotYetConnectedException {
this.conn.send(data);
}
public void run() {
if (this.writethread == null) {
this.writethread = Thread.currentThread();
}
this.interruptableRun();
assert !this.channel.isOpen();
}
private final void interruptableRun() {
if (this.channel != null) {
try {
String host;
int port;
if (this.proxyAddress != null) {
host = this.proxyAddress.getHostName();
port = this.proxyAddress.getPort();
} else {
host = this.uri.getHost();
port = this.getPort();
}
this.channel.connect(new InetSocketAddress(host, port));
this.conn.channel = this.wrappedchannel = this.createProxyChannel(this.wsfactory.wrapChannel(this.channel, (SelectionKey)null, host, port));
this.timeout = 0;
this.sendHandshake();
this.readthread = new Thread(new WebSocketClient.WebsocketWriteThread());
this.readthread.start();
} catch (ClosedByInterruptException var3) {
this.onWebsocketError((WebSocket)null, var3);
return;
} catch (Exception var4) {
this.onWebsocketError(this.conn, var4);
this.conn.closeConnection(-1, var4.getMessage());
return;
}
ByteBuffer buff = ByteBuffer.allocate(WebSocketImpl.RCVBUF);
try {
while(this.channel.isOpen()) {
if (SocketChannelIOHelper.read(buff, this.conn, this.wrappedchannel)) {
this.conn.decode(buff);
} else {
this.conn.eot();
}
if (this.wrappedchannel instanceof WrappedByteChannel) {
WrappedByteChannel w = (WrappedByteChannel)this.wrappedchannel;
if (w.isNeedRead()) {
while(SocketChannelIOHelper.readMore(buff, this.conn, w)) {
this.conn.decode(buff);
}
this.conn.decode(buff);
}
}
}
} catch (CancelledKeyException var5) {
this.conn.eot();
} catch (IOException var6) {
this.conn.eot();
} catch (RuntimeException var7) {
this.onError(var7);
this.conn.closeConnection(1006, var7.getMessage());
}
}
}
private int getPort() {
int port = this.uri.getPort();
if (port == -1) {
String scheme = this.uri.getScheme();
if (scheme.equals("wss")) {
return 443;
} else if (scheme.equals("ws")) {
return 80;
} else {
throw new RuntimeException("unkonow scheme" + scheme);
}
} else {
return port;
}
}
private void sendHandshake() throws InvalidHandshakeException {
String part1 = this.uri.getPath();
String part2 = this.uri.getQuery();
String path;
if (part1 != null && part1.length() != 0) {
path = part1;
} else {
path = "/";
}
if (part2 != null) {
path = path + "?" + part2;
}
int port = this.getPort();
String host = this.uri.getHost() + (port != 80 ? ":" + port : "");
HandshakeImpl1Client handshake = new HandshakeImpl1Client();
handshake.setResourceDescriptor(path);
handshake.put("Host", host);
if (this.headers != null) {
Iterator i$ = this.headers.entrySet().iterator();
while(i$.hasNext()) {
Entry<String, String> kv = (Entry)i$.next();
handshake.put((String)kv.getKey(), (String)kv.getValue());
}
}
this.conn.startHandshake(handshake);
}
public READYSTATE getReadyState() {
return this.conn.getReadyState();
}
public final void onWebsocketMessage(WebSocket conn, String message) {
this.onMessage(message);
}
public final void onWebsocketMessage(WebSocket conn, ByteBuffer blob) {
this.onMessage(blob);
}
public final void onWebsocketOpen(WebSocket conn, Handshakedata handshake) {
this.connectLatch.countDown();
this.onOpen((ServerHandshake)handshake);
}
public final void onWebsocketClose(WebSocket conn, int code, String reason, boolean remote) {
this.connectLatch.countDown();
this.closeLatch.countDown();
if (this.readthread != null) {
this.readthread.interrupt();
}
this.onClose(code, reason, remote);
}
public final void onWebsocketError(WebSocket conn, Exception ex) {
this.onError(ex);
}
public final void onWriteDemand(WebSocket conn) {
}
public void onWebsocketCloseInitiated(WebSocket conn, int code, String reason) {
this.onCloseInitiated(code, reason);
}
public void onWebsocketClosing(WebSocket conn, int code, String reason, boolean remote) {
this.onClosing(code, reason, remote);
}
public void onCloseInitiated(int code, String reason) {
}
public void onClosing(int code, String reason, boolean remote) {
}
public WebSocket getConnection() {
return this.conn;
}
public final void setWebSocketFactory(WebSocketClient.WebSocketClientFactory wsf) {
this.wsfactory = wsf;
}
public final WebSocketFactory getWebSocketFactory() {
return this.wsfactory;
}
public InetSocketAddress getLocalSocketAddress(WebSocket conn) {
return this.channel != null ? (InetSocketAddress)this.channel.socket().getLocalSocketAddress() : null;
}
public InetSocketAddress getRemoteSocketAddress(WebSocket conn) {
return this.channel != null ? (InetSocketAddress)this.channel.socket().getLocalSocketAddress() : null;
}
public abstract void onOpen(ServerHandshake var1);
public abstract void onMessage(String var1);
public abstract void onClose(int var1, String var2, boolean var3);
public abstract void onError(Exception var1);
public void onMessage(ByteBuffer bytes) {
}
public ByteChannel createProxyChannel(ByteChannel towrap) {
return (ByteChannel)(this.proxyAddress != null ? new WebSocketClient.DefaultClientProxyChannel(towrap) : towrap);
}
public void setProxy(InetSocketAddress proxyaddress) {
this.proxyAddress = proxyaddress;
}
private class WebsocketWriteThread implements Runnable {
private WebsocketWriteThread() {
}
public void run() {
Thread.currentThread().setName("WebsocketWriteThread");
try {
while(!Thread.interrupted()) {
SocketChannelIOHelper.writeBlocking(WebSocketClient.this.conn, WebSocketClient.this.wrappedchannel);
}
} catch (IOException var2) {
WebSocketClient.this.conn.eot();
} catch (InterruptedException var3) {
}
}
}
public interface WebSocketClientFactory extends WebSocketFactory {
ByteChannel wrapChannel(SocketChannel var1, SelectionKey var2, String var3, int var4) throws IOException;
}
public class DefaultClientProxyChannel extends AbstractClientProxyChannel {
public DefaultClientProxyChannel(ByteChannel towrap) {
super(towrap);
}
public String buildHandShake() {
StringBuilder b = new StringBuilder();
String host = WebSocketClient.this.uri.getHost();
b.append("CONNECT ");
b.append(host);
b.append(":");
b.append(WebSocketClient.this.getPort());
b.append(" HTTP/1.1\n");
b.append("Host: ");
b.append(host);
b.append("\n");
return b.toString();
}
}
}
The third-party library has a description. You can write a class to inherit the WebSocketClient class and rewrite the code after network disconnection and reconnection. The code example of the third-party library is provided for reference.
I have problem of playing back the recorded media file from red5 published stream, following is my code. I could see a file called out.flv is created, but this out.flv can not be played back.
public class Red5ClientTest {
private static Timer timer;
private static RTMPClient client;
private static String sourceStreamName;
private static int videoTs;
private static int audioTs;
private static FLVWriter writer;
private static int bytesRead =0;
public static void main(String[] args) throws IOException {
String sourceHost = "localhost";
int sourcePort = 1935;
String sourceApp = "oflaDemo";
sourceStreamName = "myStream";
timer = new Timer();
client = new RTMPClient();
String path = "c:\\temp\\out.flv";
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
writer = new FLVWriter(file,true);
client.setStreamEventDispatcher(new StreamEventDispatcher());
client.setStreamEventHandler(new INetStreamEventHandler() {
public void onStreamEvent(Notify notify) {
System.out.printf("onStreamEvent: %s\n", notify);
ObjectMap<?, ?> map = (ObjectMap<?, ?>) notify.getCall().getArguments()[0];
String code = (String) map.get("code");
System.out.printf("<:%s\n", code);
if (StatusCodes.NS_PLAY_STREAMNOTFOUND.equals(code)) {
System.out.println("Requested stream was not found");
client.disconnect();
}
else if (StatusCodes.NS_PLAY_UNPUBLISHNOTIFY.equals(code)
|| StatusCodes.NS_PLAY_COMPLETE.equals(code)) {
System.out.println("Source has stopped publishing or play is complete");
client.disconnect();
}
}
});
client.setConnectionClosedHandler(new Runnable() {
public void run() {
if (writer != null) {
writer.close();
}
System.out.println("Source connection has been closed, proxy will be stopped");
System.exit(0);
}
});
client.setExceptionHandler(new ClientExceptionHandler() {
#Override
public void handleException(Throwable throwable) {
throwable.printStackTrace();
System.exit(1);
}
});
// connect the consumer
Map<String, Object> defParams = client.makeDefaultConnectionParams(sourceHost, sourcePort,
sourceApp);
// add pageurl and swfurl
defParams.put("pageUrl", "");
defParams.put("swfUrl", "app:/Red5-StreamRelay.swf");
// indicate for the handshake to generate swf verification data
client.setSwfVerification(true);
// connect the client
client.connect(sourceHost, sourcePort, defParams, new IPendingServiceCallback() {
public void resultReceived(IPendingServiceCall call) {
System.out.println("connectCallback");
ObjectMap<?, ?> map = (ObjectMap<?, ?>) call.getResult();
String code = (String) map.get("code");
if ("NetConnection.Connect.Rejected".equals(code)) {
System.out.printf("Rejected: %s\n", map.get("description"));
client.disconnect();
//proxy.stop();
}
else if ("NetConnection.Connect.Success".equals(code)) {
// 1. Wait for onBWDone
timer.schedule(new BandwidthStatusTask(), 2000L);
Object result = call.getResult();
System.out.println("Red5ClientTest.main()");
}
else {
System.out.printf("Unhandled response code: %s\n", code);
}
}
});
// keep sleeping main thread while the proxy runs
// kill the timer
//timer.cancel();
System.out.println("Stream relay exit");
}
/**
* Handles result from subscribe call.
*/
private static final class SubscribeStreamCallBack implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
System.out.println("resultReceived: " + call);
Object result = call.getResult();
System.out.println("results came {}" + result);
}
}
private static final class StreamEventDispatcher implements IEventDispatcher {
public void dispatchEvent(IEvent event) {
System.out.println("ClientStream.dispachEvent()" + event.toString());
try {
//RTMPMessage build = RTMPMessage.build((IRTMPEvent) event);
IRTMPEvent rtmpEvent = (IRTMPEvent) event;
ITag tag = new Tag();
tag.setDataType(rtmpEvent.getDataType());
if (rtmpEvent instanceof VideoData) {
videoTs += rtmpEvent.getTimestamp();
tag.setTimestamp(videoTs);
}
else if (rtmpEvent instanceof AudioData) {
audioTs += rtmpEvent.getTimestamp();
tag.setTimestamp(audioTs);
}
IoBuffer data = ((IStreamData) rtmpEvent).getData().asReadOnlyBuffer();
tag.setBodySize(data.limit());
tag.setBody(data);
try {
writer.writeTag(tag);
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("writting....");
}
catch (Exception e) {//IOException
e.printStackTrace();
}
}
}
private static final class BandwidthStatusTask extends TimerTask {
#Override
public void run() {
// check for onBWDone
System.out.println("Bandwidth check done: " + client.isBandwidthCheckDone());
// cancel this task
this.cancel();
// create a task to wait for subscribed
timer.schedule(new PlayStatusTask(), 1000L);
// 2. send FCSubscribe
client.subscribe(new SubscribeStreamCallBack(), new Object[] { sourceStreamName });
}
}
private static final class PlayStatusTask extends TimerTask {
#Override
public void run() {
// checking subscribed
System.out.println("Subscribed: " + client.isSubscribed());
// cancel this task
this.cancel();
// 3. create stream
client.createStream(new CreateStreamCallback());
}
}
/**
* Creates a "stream" via playback, this is the source stream.
*/
private static final class CreateStreamCallback implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
System.out.println("resultReceived: " + call);
int streamId = ((Number) call.getResult()).intValue();
System.out.println("stream id: " + streamId);
// send our buffer size request
if (sourceStreamName.endsWith(".flv") || sourceStreamName.endsWith(".f4v")
|| sourceStreamName.endsWith(".mp4")) {
client.play(streamId, sourceStreamName, 0, -1);
}
else {
client.play(streamId, sourceStreamName, -1, 0);
}
}
}
}
what could I be doing possibly wrong here?
Finally got it
public class TeqniRTMPClient {
private static final Logger logger = LoggerFactory.getLogger(MyRtmpClient.class);
public static void main(String args[]) throws IOException {
TeqniRTMPClient client = new TeqniRTMPClient("localhost", 1935, "oflaDemo", "myStream");
client.recordStream();
}
private RTMPClient client;
private ITagWriter writer;
private String sourceHost;
private int sourcePort;
private String sourceApp;
private String sourceStreamName;
private int lastTimestamp;
private int startTimestamp = -1;
public TeqniRTMPClient(String sourceHost, int sourcePort, String sourceApp,
String sourceStreamName) {
super();
this.sourceHost = sourceHost;
this.sourcePort = sourcePort;
this.sourceApp = sourceApp;
this.sourceStreamName = sourceStreamName;
}
public void recordStream() throws IOException {
client = new RTMPClient();
String path = "c:\\temp\\out.flv";
File file = new File(path);
if (!file.exists()) {
file.createNewFile();
}
FLVService flvService = new FLVService();
flvService.setGenerateMetadata(true);
try {
IStreamableFile flv = flvService.getStreamableFile(file);
writer = flv.getWriter();
}
catch (Exception e) {
throw new RuntimeException(e);
}
client.setStreamEventDispatcher(new StreamEventDispatcher());
client.setStreamEventHandler(new INetStreamEventHandler() {
public void onStreamEvent(Notify notify) {
System.out.printf("onStreamEvent: %s\n", notify);
ObjectMap<?, ?> map = (ObjectMap<?, ?>) notify.getCall().getArguments()[0];
String code = (String) map.get("code");
System.out.printf("<:%s\n", code);
if (StatusCodes.NS_PLAY_STREAMNOTFOUND.equals(code)) {
System.out.println("Requested stream was not found");
client.disconnect();
}
else if (StatusCodes.NS_PLAY_UNPUBLISHNOTIFY.equals(code)
|| StatusCodes.NS_PLAY_COMPLETE.equals(code)) {
System.out.println("Source has stopped publishing or play is complete");
client.disconnect();
}
}
});
client.setExceptionHandler(new ClientExceptionHandler() {
#Override
public void handleException(Throwable throwable) {
throwable.printStackTrace();
System.exit(1);
}
});
client.setConnectionClosedHandler(new Runnable() {
public void run() {
if (writer != null) {
writer.close();
}
System.out.println("Source connection has been closed, proxy will be stopped");
System.exit(0);
}
});
// connect the consumer
Map<String, Object> defParams = client.makeDefaultConnectionParams(sourceHost, sourcePort,
sourceApp);
// add pageurl and swfurl
defParams.put("pageUrl", "");
defParams.put("swfUrl", "app:/Red5-StreamRelay.swf");
// indicate for the handshake to generate swf verification data
client.setSwfVerification(true);
// connect the client
client.connect(sourceHost, sourcePort, defParams, new IPendingServiceCallback() {
public void resultReceived(IPendingServiceCall call) {
System.out.println("connectCallback");
ObjectMap<?, ?> map = (ObjectMap<?, ?>) call.getResult();
String code = (String) map.get("code");
if ("NetConnection.Connect.Rejected".equals(code)) {
System.out.printf("Rejected: %s\n", map.get("description"));
client.disconnect();
}
else if ("NetConnection.Connect.Success".equals(code)) {
// 1. Wait for onBWDone
client.createStream(new CreateStreamCallback());
Object result = call.getResult();
System.out.println("Red5ClientTest.main()");
}
else {
System.out.printf("Unhandled response code: %s\n", code);
}
}
});
}
class CreateStreamCallback implements IPendingServiceCallback {
public void resultReceived(IPendingServiceCall call) {
System.out.println("resultReceived: " + call);
int streamId = ((Number) call.getResult()).intValue();
System.out.println("stream id: " + streamId);
// send our buffer size request
if (sourceStreamName.endsWith(".flv") || sourceStreamName.endsWith(".f4v")
|| sourceStreamName.endsWith(".mp4")) {
client.play(streamId, sourceStreamName, 0, -1);
}
else {
client.play(streamId, sourceStreamName, -1, 0);
}
}
}
class StreamEventDispatcher implements IEventDispatcher {
private int videoTs;
private int audioTs;
public void dispatchEvent(IEvent event) {
System.out.println("ClientStream.dispachEvent()" + event.toString());
try {
IRTMPEvent rtmpEvent = (IRTMPEvent) event;
logger.debug("rtmp event: " + rtmpEvent.getHeader() + ", "
+ rtmpEvent.getClass().getSimpleName());
if (!(rtmpEvent instanceof IStreamData)) {
logger.debug("skipping non stream data");
return;
}
if (rtmpEvent.getHeader().getSize() == 0) {
logger.debug("skipping event where size == 0");
return;
}
byte dataType = rtmpEvent.getDataType();
ITag tag = new Tag();
tag.setDataType(dataType);
if (rtmpEvent instanceof VideoData) {
VideoData video = (VideoData) rtmpEvent;
FrameType frameType = video.getFrameType();
videoTs += rtmpEvent.getTimestamp();
tag.setTimestamp(videoTs);
}
else if (rtmpEvent instanceof AudioData) {
audioTs += rtmpEvent.getTimestamp();
tag.setTimestamp(audioTs);
}
IoBuffer data = ((IStreamData) rtmpEvent).getData().asReadOnlyBuffer();
tag.setBodySize(data.limit());
tag.setBody(data);
try {
writer.writeTag(tag);
}
catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println("writting....");
}
catch (Exception e) {//IOException
e.printStackTrace();
}
}
}
}
I am learning Vaadin from the Vaadin 7 CookBook, on chapter 3 the authors show an example of a drag and drop uploader using StreamVariable and Html5File, here is the code:
public class DragAndDropUploader extends VerticalLayout {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final String REPOSITORY = VaadinService.getCurrent().getBaseDirectory().getAbsolutePath()+"/WEB-INF/vaadin-repo/";
public DragAndDropUploader() {
final Table table = new Table();
table.setSizeFull();
table.addContainerProperty("File name", String.class, null);
table.addContainerProperty("Size", String.class, null);
table.addContainerProperty("Progress", ProgressBar.class, null);
DragAndDropWrapper dropTable = new DragAndDropWrapper(table);
dropTable.setDropHandler(new DropHandler() {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public void drop(DragAndDropEvent event) {
WrapperTransferable transferred = (WrapperTransferable) event.getTransferable();
Html5File[] files = transferred.getFiles();
if (files != null) {
for (Html5File file : files) {
ProgressBar progressBar = new ProgressBar();
progressBar.setSizeFull();
UI.getCurrent().setPollInterval(100);
table.addItem(new Object[] { file.getFileName(),
getSizeAsString(file.getFileSize()),
progressBar
}, null);
StreamVariable streamVariable = createStreamVariable(file, progressBar);
file.setStreamVariable(streamVariable);
}
}
else {
Notification.show("Usupported file type", Type.ERROR_MESSAGE);
}
}
#Override
public AcceptCriterion getAcceptCriterion() {
return AcceptAll.get();
}
});
addComponent(dropTable);
setSizeUndefined();
}
private StreamVariable createStreamVariable(final Html5File file, final ProgressBar progressBar) {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
return new StreamVariable() {
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
public void streamingStarted(StreamingStartEvent event) {
}
#Override
public void streamingFinished(StreamingEndEvent event) {
try {
FileOutputStream fos = new FileOutputStream(REPOSITORY+file.getFileName());
System.out.println(outputStream.size()+ ": "+outputStream.toString() + " - " +fos.toString());
outputStream.writeTo(fos);
} catch (IOException e) {
Notification.show("Streaming finished failing, please, retry", Type.ERROR_MESSAGE);
}
progressBar.setValue(new Float(1.0));
}
#Override
public void streamingFailed(StreamingErrorEvent event) {
Notification.show("Streaming failed, please, try again", Type.ERROR_MESSAGE);
}
#Override
public void onProgress(StreamingProgressEvent event) {
progressBar.setValue((float) event.getBytesReceived() / file.getFileSize());
}
#Override
public boolean listenProgress() {
return true;
}
#Override
public boolean isInterrupted() {
return false;
}
#Override
public OutputStream getOutputStream() {
return outputStream;
}
};
}
private String getSizeAsString(long size) {
String unit = "B";
int kB, MB;
if (size >= (kB = (2 << 10))) {
size = size / kB;
unit = "kB";
}
else if (size >= (MB = 2 << 20)) {
size = size / MB;
}
return size + " " + unit;
}
}
REPOSITORY is a path to a vaadin-repo folder inside WebContent/WEB-INF.
My problem is that outputStream.writeTo(fos); where actually the file should be written to the server:
#Override
public void streamingFinished(StreamingEndEvent event) {
try {
FileOutputStream fos = new FileOutputStream(REPOSITORY+file.getFileName());
System.out.println(outputStream.size()+ ": "+outputStream.toString() + " - " +fos.toString());
outputStream.writeTo(fos);
} catch (IOException e) {
Notification.show("Streaming finished failing, please, retry", Type.ERROR_MESSAGE);
}
progressBar.setValue(new Float(1.0));
}
But it's not. When I make an upload and then check that vaadin-repo folder, it remains empty...
I do not get any exceptions (no FileNotFoundException, no IOException), so the problem is not that. REPOSITORY path have some spaces (but I think that this is not the problem (as I said I don't get any FileNotFoundException), and I have implemented Vaadin's uploaders previously (via the Upload.Receiver inner interface)).
Where is the problem?
Your code seems to be correct and a similar version is working for me. The only problem seems to be that you're not closing the streams. Make sure you close both outputstream and the FileOutputStream fos.
Basically, we have a class called OfficeManger which acts as a driver to connect to openoffice software, it needs to be connected all the time so we can use the converter to convert documents. We start the OpenOfficeProcess during the start of the web application, which starts fine. But looks like the executor which running in init() is on different thread and we couldn't able to get the running instance of OfficeManager. How to run in its own thread so that I can have this instance called from different class to use the converter method?
OfficeDocumentConverter converter = OpenOfficeProcessor.getInstance().getDocumentConverter();
converter.convert(inputFile, outputFile, pdf);
OpenOfficeProcessor
public class OpenOfficeProcessor {
private static final OpenOfficeProcessor INSTANCE = new OpenOfficeProcessor();
static ExecutorService executor = Executors.newSingleThreadExecutor();
private final OfficeManager officeManager;
private final OfficeDocumentConverter documentConverter;
public OpenOfficeProcessor(){
DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
String homePath = ConfigurationManager.getApplicationProperty(ConfigurationManager.OPENOFFICE_HOME_PATH);
if(homePath != null){
configuration.setOfficeHome(homePath);
} else {
LOG.error("OpenOffice.home.path is not set in the properties file");
new Throwable("Please set OPENOFFICE.HOME.PATH parameter in the properties file");
}
String port = ConfigurationManager.getApplicationProperty(ConfigurationManager.OPENOFFICE_LISTENER_PORT);
if( port != null){
configuration.setPortNumber(Integer.parseInt(port));
}else {
LOG.error("openoffice.listener.port is not set in the properties file");
}
String executionTimeout = ConfigurationManager.getApplicationProperty(ConfigurationManager.OPENOFFICE_EXECUTION_TIMEOUT);
if(executionTimeout != null){
configuration.setTaskExecutionTimeout(Long.parseLong(executionTimeout));
}
String pipeNames = ConfigurationManager.getApplicationProperty(ConfigurationManager.OPENOFFICE_PIPES_NAMES);
if(ConfigurationManager.getApplicationProperty(ConfigurationManager.OPENOFFICE_PIPES_NAMES)!= null){
configuration.setPipeNames(pipeNames);
}
officeManager = configuration.buildOfficeManager();
documentConverter = new OfficeDocumentConverter(officeManager);
}
public static OpenOfficeProcessor getInstance()
{
return INSTANCE;
}
protected static void init() {
LOG.debug("Starting the open office listener...");
executor.submit(new Callable(){
#Override
public Object call() throws Exception {
OpenOfficeProcessor.getInstance().officeManager.start();
return null;
}
});
}
protected static void destroy() {
LOG.debug("Stopping the open office listener...");
OpenOfficeProcessor.getInstance().officeManager.stop();
}
public OfficeManager getOfficeManager() {
return officeManager;
}
public OfficeDocumentConverter getDocumentConverter() {
return documentConverter;
}
}
OfficeManager
public interface OfficeManager {
void execute(OfficeTask task) throws OfficeException;
void start() throws OfficeException;
void stop() throws OfficeException;
boolean isRunning();
}
I am working on a project where I send supposedly press a button on a webpage and it then executes a command in java. What I'm looking for is something like this. Say if I pressed a button and then it sends a command to the minecraft server to reload plugins. How would I go achieving this? Thanks
When you have to comunicate between different applications you will problably need a bridge. In your case I'd suggest to use Minecraft's RCON service (must be enabled in the confingiration) or a plugin that do something similar, like Websend.
Websend code is actually available on Github if you would like to know how the plugin work.
Connection between PHP and Java through sockets
Step 1:
Create a java server
I have created a nice API for these situations. you can use them if you would like:
ChatServer
all you need to do is create a new instance of this class
package com.weebly.foxgenesis.src;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.io.*;
public final class ChatServer implements Runnable
{
private final int CLIENTMAXIMUM;
private ChatServerThread clients[];
private ServerSocket server = null;
private Thread thread = null;
private int clientCount = 0;
private final ServerReciever output;
private List<ConnectHandler> connectHandlers = new ArrayList<ConnectHandler>();
private List<QuitHandler> quitHandlers = new ArrayList<QuitHandler>();
/**
* creates a new ChatServer for connection between clients
* #param a ServerReciever implementing class
*/
public ChatServer(ServerReciever a)
{
CLIENTMAXIMUM = a.getMaximunClients();
output = a;
clients = new ChatServerThread[CLIENTMAXIMUM];
try
{
server = new ServerSocket();
server.bind(new InetSocketAddress(output.getHost(), output.getPort()));
log(server);
start();
}
catch(IOException ioe)
{
error("Can not bind to port " + a.getPort() + ": " + ioe.getMessage());
}
}
/**
* Force the Server to handle a msg
*/
public void add(String text)
{
output.handle(text);
}
/**
* Force the Server to handle an error
*/
public void error(String text)
{
output.handleError(text);
}
/**
* Log to the server
*/
public void log(Object text)
{
output.handleLog(text);
}
/**
* send a message to a specific client
* #param ID ID of client
* #param msg
*/
public void send(int ID, String msg)
{
clients[findClient(ID)].send(msg);
add(msg);
}
/**
* Called by runnable
*/
public void run()
{
while (thread != null)
{
try
{
if(clientCount != CLIENTMAXIMUM){
log("Waiting for a client ...");
addThread(server.accept());
}
}
catch(IOException ioe)
{
error("Server accept error: " + ioe);
stop();
}
}
}
private void start()
{
if (thread == null)
{
thread = new Thread(this);
thread.start();
}
}
/**
* Stops the server
*/
#SuppressWarnings("deprecation")
public void stop()
{
if (thread != null)
{
thread.stop();
thread = null;
}
}
private int findClient(int ID)
{
for (int i = 0; i < clientCount; i++)
if (clients[i].getID() == ID)
return i;
return -1;
}
/**
* sends a message to a
* #param ID
* #param input
*/
public synchronized void handle(int ID, String input)
{
StringTokenizer t = new StringTokenizer(input);
String[] arg = new String[t.countTokens()];
for(int i=0; t.hasMoreElements(); i++)
arg[i] = t.nextToken(",");
if(arg[0] == "new")
switch(input)
{
case".bye":
{
clients[findClient(ID)].send(".bye");
remove(ID);
break;
}
default:
{
for (int i = 0; i < clientCount; i++)
clients[i].send(input);
break;
}
}
}
/**
* sends a message to all clients
* #param input message to send
*/
public void sendAll(String input)
{
for (int i = 0; i < clientCount; i++)
clients[i].send(input);
}
/**
* remove a selected ID
* #param ID ID of client
*/
#SuppressWarnings("deprecation")
public synchronized void remove(int ID)
{
int pos = findClient(ID);
if (pos >= 0)
{
ChatServerThread toTerminate = clients[pos];
log("Removing client thread " + ID + " at " + pos);
if (pos < clientCount-1)
for (int i = pos+1; i < clientCount; i++)
clients[i-1] = clients[i];
clientCount--;
QuitEvent e = new QuitEvent(toTerminate.getID());
e.setGameBreaking(true);
for(QuitHandler a: quitHandlers)
a.quit(e);
try
{
toTerminate.close(); }
catch(IOException ioe)
{
error("Error closing thread: " + ioe);
}
toTerminate.stop();
}
}
private void addThread(Socket socket)
{
if (clientCount < clients.length)
{
log("Client accepted: " + socket);
clients[clientCount] = new ChatServerThread(this, socket);
try
{
clients[clientCount].open();
clients[clientCount].start();
ClientConnectEvent e = new ClientConnectEvent(clients[clientCount],clients[clientCount].getID());
clientCount++;
for(ConnectHandler a: connectHandlers)
a.connect(e);
}
catch(IOException ioe)
{
error("Error opening thread: " + ioe);
}
}
else
error("Client refused: maximum " + clients.length + " reached.");
}
public String toString()
{
return "ChatServer{;host=" + output.getHost() + ";port=" + output.getPort() + ";clients=" + clientCount + ";}";
}
public int getAmountOfClients()
{
return clientCount;
}
public void addConnectHandler(ConnectHandler handler)
{
connectHandlers.add(handler);
}
public void removeConnectHandler(ConnectHandler handler)
{
connectHandlers.remove(handler);
}
public int getMaxClients()
{
return CLIENTMAXIMUM;
}
public void addQuitHandler(QuitHandler quitHandler)
{
quitHandlers.add(quitHandler);
}
public void removeQuitHandler(QuitHandler quithandler)
{
quitHandlers.remove(quithandler);
}
}
ChatServerThread
Used by the ChatServer as client connections
package com.weebly.foxgenesis.src;
import java.net.*;
import java.io.*;
public final class ChatServerThread extends Thread
{
private ChatServer server = null;
private Socket socket = null;
private int ID = -1;
private DataInputStream streamIn = null;
private DataOutputStream streamOut = null;
public ChatServerThread(ChatServer server, Socket socket)
{
super();
this.server = server;
this.socket = socket;
this.ID = socket.getPort();
}
#SuppressWarnings("deprecation")
public void send(String msg)
{
try
{
streamOut.writeUTF(msg);
streamOut.flush();
}
catch(IOException ioe)
{
server.error(ID + " ERROR sending: " + ioe.getMessage());
server.remove(ID);
stop();
}
}
public int getID()
{
return ID;
}
#SuppressWarnings("deprecation")
#Override
public void run()
{
server.log("Server Thread " + ID + " running.");
while (true)
{
try
{
server.handle(ID, streamIn.readUTF());
}
catch(IOException ioe)
{
server.error(ID + " ERROR reading: " + ioe.getMessage());
server.remove(ID);
stop();
}
}
}
public void open() throws IOException
{
streamIn = new DataInputStream(new
BufferedInputStream(socket.getInputStream()));
streamOut = new DataOutputStream(new
BufferedOutputStream(socket.getOutputStream()));
}
public void close() throws IOException
{
if (socket != null) socket.close();
if (streamIn != null) streamIn.close();
if (streamOut != null) streamOut.close();
}
}
ClientConnectEvent
package com.weebly.foxgenesis.src;
public class ClientConnectEvent extends ConnectionEvent
{
private final ChatServerThread client;
public ClientConnectEvent(ChatServerThread client, int clientID)
{
super(clientID);
this.client = client;
}
public ChatServerThread getClient()
{
return client;
}
#Override
public boolean isConnectionBreaking(){return false;}
}
ConnectHandler
package com.weebly.foxgenesis.src;
public interface ConnectHandler
{
public void connect(ClientConnectEvent e);
}
ClientQuitEvent
package com.weebly.foxgenesis.src;
public class ClientQuitEvent extends ConnectionEvent
{
public ClientQuitEvent(int clientID)
{
super(clientID);
}
#Override
public boolean isConnectionBreaking()
{
return true;
}
}
QuitHandler
package com.weebly.foxgenesis.src;
public interface QuitHandler
{
public void quit(ClientQuitEvent e);
}
ServerReciever
package com.weebly.foxgenesis.src;
public interface ServerReciever
{
public void handle(String msg);
public void handleError(String msg);
public int getPort();
public int getMaximunClients();
public void handleLog(Object text);
public String getHost();
}
ConnectionEvent
package com.weebly.foxgenesis.src;
public abstract class ConnectionEvent
{
public abstract boolean isConnectionBreaking();
private int clientID;
public ConnectionEvent(int clientID)
{
this.clientID = clientID;
}
public int getClientID()
{
return clientID;
}
}
Step 2:
Connect Server to Bukkit
i have provided an example on how to connect the server to bukkit by making a new plugin.
public class MyPlugin extends JavaPlugin
{
#Override
public void onEnable()
{
ChatServer server = new ChatServer(new ServerReciever()
{
#Override
public void handle(String msg){handleMsg(msg);}
#Override
public void handleError(String msg){handleErr(msg);}
#Override
public int getPort(){return 25567}
#Override
public int getMaximunClients(){return 100;}
#Override
public void handleLog(Object text){log(text);}
#Override
public String getHost(){return "localhost";}
}
}
public void handleLog(Object text)
{
System.out.println(text);
}
public void handelErr(String msg)
{
System.err.println(msg);
}
public void handleMsg(String msg)
{
if(msg.equalsIgnoreCase("reload"))
Bukkit.reloadOrSomething(); //i don't know the void off the top of my head
}
}
Step 3:
Port Forward
if you don't know what that is go ahead and google it. there are some great tutorials online. you want to port forward the port that you set in the code.
Step 4:
Send a message to the Server
i do not know PHP but all you need to do is send a UTF-8 Encoded message to the server's ip on the port that you hard coded above.
Step 5:
ENJOY!