msgbartop
Various ramblings-on, mostly about Red5
msgbarbottom

25 May 09 Memory leak?

A poster to the Red5 list posted this today and claims that it exposes a memory leak in the server. The individual states that he doesnt know Java very well, so having been in the Java-game for 10+ years I immediately spot a potential leak in his method.

public void privMessage(String sendto, String message) {
IConnection conn = Red5.getConnectionLocal();
IClient client = conn.getClient();
IScope scope = getScope();
IContext context = getContext();
IClientRegistry reg = context.getClientRegistry();
if (reg.hasClient(sendto)) {
IClient recip = reg.lookupClient(sendto);
Set[IConnection] rcons = recip.getConnections(scope);
Iterator[IConnection] it = rcons.iterator();
while (it.hasNext()) {
IConnection rcon = it.next();
if (rcon instanceof IServiceCapableConnection)
((IServiceCapableConnection) rcon).invoke("privComm", new Object[]{client.getId(),message});
}
}
}

The big red flag for me is the use of an Iterator and the second thing is the use of an object reference within a loop. So to fix these potential leak candidates, I offer two solutions below.

Removal of the Iterator by using for-each:

IConnection conn = Red5.getConnectionLocal();
IClient client = conn.getClient();
IContext context = getContext();
IClientRegistry reg = context.getClientRegistry();
if (reg.hasClient(sendto)) {
IClient recip = reg.lookupClient(sendto);
String clientId = client.getId();
Set[IConnection] rcons = recip.getConnections(scope);
for (IConnection rcon : rcons) {
if (rcon instanceof IServiceCapableConnection)
((IServiceCapableConnection) rcon).invoke("privComm", new Object[]{clientId,message});
break;
}
}

Overall I think this is the best solution and is what I would implement:

1. In your ApplicationAdapter, create a map containing your client id to connection mappings

// map to keep track of connections by client id
private static ConcurrentMap[String, IConnection] connectionMap = new ConcurrentHashMap[String, IConnection](31);

2. In your connect method, add the incomming clients to the map

@Override
public boolean connect(final IConnection conn, IScope scope, Object[] params) {
// call original method of parent class
if (!super.connect(conn, scope, params)) {
return false;
}
// get the connections client id
IClient client = conn.getClient();
if (client != null) {
String clientId = client.getId();
// check the map for the client
if (!connectionMap.containsKey(clientId)) {
// register the connection
connectionMap.put(clientId, conn);
} else {
log.warn("Client id {} already exists in connection map",
clientId);
}
}
return true;
}

3. Simplify your method

public void privMessage(String sendto, String message) {
IConnection conn = Red5.getConnectionLocal();
IClient client = conn.getClient();
//senders client id
String clientId = client.getId();
if (connectionMap.containsKey(sendto)) {
IConnection rcon = connectionMap.get(sendto);
if (!ServiceUtils.invokeOnConnection(rcon, "privComm", new Object[]{clientId, message})) {
log.warn("Private message to client id: {} failed", sendto);
}
} else {
//notify sender that recipient is not available
ServiceUtils.invokeOnConnection(conn, "onError", new Object[]{"Client was not available"});
}
}

4. Dont forget to remove the map entries when the client disconnects

@Override
public void appDisconnect(IConnection conn) {
// get the previously stored id
String clientId = conn.getClient().getId();
// unregister user
IConnection cn = connectionMap.remove(clientId);
}

Please note that for the generic type args, I am using square braces for word press formatting reasons. Make sure you replace them with < and > before using the code

Tags: , , , , ,

Buzz it!

08 May 09 Flash on Tap: Red5 Workshop

FOT is coming up real soon… I’m co-presenting with Dominick for the Red5 workshop and I would like to know what you guys want to see? Since its an all-day thing, I would be glad to get some input from the community. Post your ideas as comments.

Tags: , , , , ,

Buzz it!

07 May 09 Azdroids

I wrote a new Android application today while on my “Vacation”, this one is based on one of my favorite classic games – Asteroids. I still have a lot of bugs and clean up to complete, but by looking at the screencast you can see that it is playable.

Tags: , , ,

Buzz it!

06 May 09 My first Android application

Quite some time ago, I wrote an application for the Danger Hiptop that displayed falling text like in the Matrix. I have decided to port this to Android as my first “learning” application. Here is a screencast of my first “working” version. I also want to point out that I wasn’t able to port the application but instead have rewritten it from scratch; which is probably better in the long-run.

After having some other things to do etc.. heres an update after 2 or so hours

Ok, so I went and had dinner with the family and then worked on it a bit more, without further adieu –
Best and latest build

I have also packaged it up as an unsigned apk, but you cannot load this unless your phone has Cupcake (1.5); which for me and the rest of the US is sometime next week. :(

Tags: , ,

Buzz it!

05 May 09 Support for other SLF4J loggers

I recently updated Red5 trunk to fix APPSERVER-369 and this allows the use of Log4j or any other SLF4j implementation. There may be a few quirks to workout but here is the procedure for using Log4j instead of the default implementation of Logback.
1. Edit all of your application web.xml files and remove any logging context listeners or filters and replace them with this:

<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>

2. Edit your red5.bat or sh to include the slf4j adapter jar and the latest log4j jars:

set RED5_CLASSPATH=%RED5_HOME%\boot.jar;%RED5_HOME%\lib\slf4j-log4j12-1.5.6.jar;%RED5_HOME%\lib\log4j-1.2.15.jar;%RED5_HOME%\conf;%CLASSPATH%

3. While in the startup script (red5.bat/sh) you must remove this entry from the LOGGING_OPTS:

-Dlogback.ContextSelector=org.red5.logging.LoggingContextSelector

4. Remove the following jars from your red5/lib directory:

logback-core-*.jar
logback-classic-*.jar
log4j-over-slf4j-1.5.6.jar

5. Add these jars to the red5/lib directory:

log4j-1.2.15.jar
slf4j-log4j12-1.5.6.jar

6. Put your’e log4j configuration files in the red5/conf directory
7. Restart your server

Now when I did my test, I was not able to get the individual application logs so I’m not sure what is missing… maybe one of you know?

Tags: , , , , ,

Buzz it!
12,920 spam comments
blocked by
Akismet