This is just a note. If anyone know a setting which satisfy both, let me know.
1. Jquery + Flash
I'm using jquery's sliding menu and flash object in the same page. The problem is the same as this. As suggested in the page, I use wmode=transparent.
2. Linux + Firefox + Flash
When I tried this configuration, "Settings..." menu is disabled. Adobe says it is a specification (see this), since it works on Windows.
How can I solve two issues with one configuration?
Friday, June 10, 2011
Compile Red5 on Eclipse
When I tried to compile red5 at Eclipse from the source checked out from the svn, I got the compile error.
To fix this issue, I changed following two. First, change the JRE System Library to jdk. And Second change the ant's JRE to jdk.
To do first, right click the "JRE System Library", and select "Properties". Then you can see the image shown below. Select "Alternate JRE" and select the jdk.
Next, select build.xml, right click it, select "Run As" -> "Ant Build...". Then you can see the following image shown below. Select "JRE" tab, and select "Separate JRE" and chose jdk.
BUILD FAILED C:\opt\workspace\red5_server\build.xml:225: The following error occurred while executing this line: C:\opt\workspace\red5_server\build.xml:246: Error running javac.exe compiler
To fix this issue, I changed following two. First, change the JRE System Library to jdk. And Second change the ant's JRE to jdk.
To do first, right click the "JRE System Library", and select "Properties". Then you can see the image shown below. Select "Alternate JRE" and select the jdk.
Next, select build.xml, right click it, select "Run As" -> "Ant Build...". Then you can see the following image shown below. Select "JRE" tab, and select "Separate JRE" and chose jdk.
Wednesday, June 1, 2011
RTMP sampler for JMeter to test flash with http
I want to have an integrated performance test environment for both HTTP and RTMP. For HTTP, JMeter is a well known tool, and has a lot of good features. But the problem is that it does not have RTMP sampler.
So I create the RTMP sampler for JMeter. I create the proxy methods using Java Sampler, and from those methods RTMPclient methods are invoked.
I use Red5 to create RTMPclient. There is a good tutorial for customizing the RTMPclient.
So I create the RTMP sampler for JMeter. I create the proxy methods using Java Sampler, and from those methods RTMPclient methods are invoked.
I use Red5 to create RTMPclient. There is a good tutorial for customizing the RTMPclient.
public class RTMPJavaSampler extends AbstractJavaSamplerClient { private static HashMap<String, MyRTMPClient> clientMap = new HashMap<String, MyRTMPClient>(); public SampleResult runTest(JavaSamplerContext ctx) { JMeterVariables vars = JMeterContextService.getContext().getVariables(); SampleResult sampleResult = new SampleResult(); boolean ret = false; if (ctx.getParameter("MethodName").equals("connect")){ ret = connect(ctx.getParameter("SessionId"), ctx.getParameter("HostIp"), ctx.getParameter("AppName"), ctx.getParameter("Arg1"), ctx.getParameter("Arg2")); } else if (ctx.getParameter("MethodName").equals("disconnect")){ ret = disconnect(ctx.getParameter("SessionId")); } if (ret) { getLogger().info("Invoke " + ctx.getParameter("MethodName") + " done." ); sampleResult.setResponseData("test success".getBytes()); sampleResult.setDataType(SampleResult.TEXT); sampleResult.setSuccessful(true); } else { getLogger().error("Failed to invoke " + ctx.getParameter("MethodName") + "."); sampleResult.setResponseData("test failed".getBytes()); sampleResult.setDataType(SampleResult.TEXT); sampleResult.setSuccessful(false); } sampleResult.setResponseCodeOK(); sampleResult.setResponseMessageOK(); return sampleResult; } @Override public Arguments getDefaultParameters() { Arguments params = new Arguments(); params.addArgument("MethodName", ""); params.addArgument("SessionId", ""); params.addArgument("HostIp", ""); params.addArgument("AppName", ""); params.addArgument("Arg1",""); params.addArgument("Arg2",""); return params; } public boolean connect(String sessionId, String hostIp, String appName, String arg1, String arg2){ MyRTMPClient client = new MyRTMPClient(); client.connect(hostIp, appName, arg1, arg2); clientMap.put(sessionId, client); while(client.getConnected()==null); return (client.getConnected()); } public boolean disconnect(String sessionId){ MyRTMPClient client = clientMap.remove(sessionId); client.disconnect(); return true; } }
public class MyRTMPClient extends RTMPClient implements IPendingServiceCallback, INetStreamEventHandler, IEventDispatcher, ClientExceptionHandler { private static final Logger logger = LoggingManager.getLoggerForClass(); private Boolean connected; public MyRTMPClient(){ setServiceProvider(this); setExceptionHandler(this); setStreamEventDispatcher(this); } public void resultReceived(IPendingServiceCall call) { Object result = call.getResult(); if ("connect".equals(call.getServiceMethodName())) { if (result instanceof ObjectMap){ @SuppressWarnings("unchecked") String code = ((ObjectMap<String, String>) result).get("code"); if (StatusCodes.NC_CONNECT_SUCCESS.equals(code)){ logger.debug("Connection Success."); connected=true; } else { logger.error("resultsReceived: " + code); connected=false; } } } else if ("createStream".equals(call.getServiceMethodName())){ if (result instanceof Integer) { Integer streamIdInt = (Integer) result; // onStreamCreated(streamIdInt); } else { logger.error("Unexpected response for createStream " + result.toString()); } } else { logger.info(call.getServiceMethodName()); } } public void connect(String host, String app, String arg1, String arg2){ Map<String, Object> defParams = makeDefaultConnectionParams(host, 1935, app); HashMap<String, Object>authParams = new HashMap<String, Object>(); authParams.put("arg1", arg1); authParams.put("arg2", arg2); Object[] params = new Object[] {authParams}; connect(host, 1935, defParams, this, params); logger.info("Connect done: " + app); } public void onStatus(Object obj){ @SuppressWarnings("unchecked") ObjectMap<String, String> map = (ObjectMap<String, String>) obj; if ("status".equals(map.get("level"))){ logger.debug("onStatus: " + obj.toString()); } else { logger.info("onStatus: " + obj.toString()); } } public void onMetaData(Object obj){ logger.info("onMetaData: " + obj.toString()); } public void onStreamEvent(Notify notify) { logger.info("onStreamEvent"); } public void dispatchEvent(IEvent event) { if (!(event instanceof IRTMPEvent)) { logger.debug("skipping non rtmp event: " + event); return; } IRTMPEvent rtmpEvent = (IRTMPEvent) event; if (rtmpEvent instanceof VideoData) { } else if (rtmpEvent instanceof AudioData) { } else if (rtmpEvent instanceof Notify){ } } public Boolean getConnected() { return connected; } }
Wednesday, April 13, 2011
How to write the Hibernate Transaction code on READ COMMITTED isolation level ?
For example, if several concurrent transactions touch the same row and increment or decrement a value of a column, the value becomes inconsistent if I use save.
@Transactional public void inc(Long id){ E e = eDao.get(id); int val = e.getCount(); e.setCount(val+1); eDao.save(e); }
Since on the following sequence:
ThreadA: val = e.getCount();
ThreadB: val = e.getCount();
ThreadA: e.setCount(val+1);
ThreadB: e.setCount(val+1);
ThreadA: eDao.save(e);
ThreadB: eDao.save(e);
The "count" column is just +1 not +2.
I think there are two solutions, though I only tried the first.
First, use an "update" hcl statement. I add following methods at eDao class, and replace above codes to eDao.incCount(id);.
public void incCount(Long id) { getSession().createQuery("update E e set e.count = e.count + 1 where e.id=:id") .setParameter("id",id) .executeUpdate(); }Since the update statement is an atomic operation (I guess), the above problem does not happen.
Second, replace eDao.save(e) to eDao.update(e).
@Transactional public void inc(Long id){ E e = eDao.get(id); int val = e.getCount(); e.setCount(val+1); eDao.update(e); // not save! }It will cause "StaleStateException" when above sequence happens. Then retry transaction when the exception happens. For example,
int retry=0; while(retry < MAX_RETRY){ try { eAccessServices.inc(id); break; } catch (StaleStateException e) { retry++; } }The above code should be written where eAccessServices.inc(id) is called.
I guess there should be better way to solve the issue. If you know it, please let me know.
Updated (04/26/2011):
This is not related to READ COMMITTED isolation level.
Thanks.
Labels:
Hibernate
Tuesday, April 5, 2011
Wicket: wicket-ajax Channel busy postponing
I got above error when using Wicket + wiQuery + wicket-push(cometd). I struggled for a day and finally, solved it.
In my case, the issue appeared on Firefox, but not happened on Chrome. Also When the page was first loaded, it worked fine. However, after reload the page, it happened. Any wicket's ajax request was blocked. And in the Wicket-Ajax-Debug window, "INFO: Channel busy postponing" message appeared.
The problem is caused by, **I guess**, wicket-ajax.js + jquery. When some jquery javascript start earlier than something, it will harm wicket-ajax.js. In my case, by cometd javascript, (see this) $.cometd.configure() and $.cometd.handshake() starts without waiting loading whole contents in the page. So I fix as follows.
This will delay the two functions to start. And problem was gone.
I'm not sure this is a right way to do. Please leave comment if you find the better solution for the same problem.
In my case, the issue appeared on Firefox, but not happened on Chrome. Also When the page was first loaded, it worked fine. However, after reload the page, it happened. Any wicket's ajax request was blocked. And in the Wicket-Ajax-Debug window, "INFO: Channel busy postponing" message appeared.
The problem is caused by, **I guess**, wicket-ajax.js + jquery. When some jquery javascript start earlier than something, it will harm wicket-ajax.js. In my case, by cometd javascript, (see this) $.cometd.configure() and $.cometd.handshake() starts without waiting loading whole contents in the page. So I fix as follows.
$(window).load(function(){ $.cometd.configure(); $.cometd.handshake(); });
This will delay the two functions to start. And problem was gone.
I'm not sure this is a right way to do. Please leave comment if you find the better solution for the same problem.
Labels:
Cometd,
JavaScript,
Wicket
How to use FlashPlayer 10.2 and 10.3 feature with Flash CS5
I want to use the new features introduced by FlashPlayer 10.2 and 10.3. More specifically, stage video and acoustic echo cancellation. Since adobe does not offer the update for Flash CS5, I have to find the other way to do it.
What I did is follow the instruction specified in the link. In this case, I set up FlashPlayer 10.3.
However there are two missing things:
The first enables to use new features, and the second enables to use stage video.
What I did is follow the instruction specified in the link. In this case, I set up FlashPlayer 10.3.
However there are two missing things:
- FlashPlayer10_3.xml: In the player node, change the version from "10" to "12". This works as "-swf-version=12" on Flex Compiler.
- Publish Settings: In the flash tab, change the "Hardware Acceleration" from "None" to "Level 2 - GPU".
The first enables to use new features, and the second enables to use stage video.
Labels:
ActionScript,
Flash
Friday, March 25, 2011
How to listen JMS disconnection?
I refere this.
public class JmsContainer extends DefaultMessageListenerContainer { private static final Logger logger = Logger.getLogger(JmsContainer.class); public void start(){ startAdvisoryListener(); super.start(); } private void startAdvisoryListener(){ javax.jms.Connection connection; try { connection = getConnectionFactory().createConnection(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); connection.start(); Destination topic = session.createTopic("ActiveMQ.Advisory..>"); MessageConsumer consumerAdvisory = session.createConsumer(topic); consumerAdvisory.setMessageListener(new MessageListener() { public void onMessage(Message message) { if (message instanceof ActiveMQMessage) { ActiveMQMessage activeMessage = (ActiveMQMessage) message; Object command = activeMessage.getDataStructure(); if (command instanceof ConsumerInfo) { logger.info("A consumer subscribed to a topic or queue: " + command); } else if (command instanceof RemoveInfo) { RemoveInfo removeInfo = (RemoveInfo) command; if (removeInfo.isConsumerRemove()) { logger.info("A consumer unsubscribed from a topic or queue"); } else { logger.info("RemoveInfo, a connection was closed: " + command); } } else if (command instanceof ConnectionInfo) { logger.info("ConnectionInfo, a new connection was made: " + command); } else { logger.info("Unknown command: " + command); } } } }); } catch (JMSException e) { e.printStackTrace(); } } }
Labels:
JMS
Subscribe to:
Posts (Atom)