Wowza Community

HTTPSession alias issue

We have the following problem for two days now, for which we can’t find a solution either in the api or your forums:

In short, we need to rewrite the stream name at the start of a http session (iphone, win8, etc.), and we need to know when that particular session for which we did the rewrite gets destroyed (basically, when a client connects we want to rewrite stream A into stream B, and when he disconnects we want to know that he originally called stream A, so we can do some ‘cleanup’ for that name)

So far this is what we have (inside the same module)

  • IMediaStreamNameAliasProvider2 gives us the entry point to rewrite the stream name, and it works ok as is (resolvePlayAlias())

  • adding IHTTPStreamerSessionNotify gives us the create and destroy events for http sessions.

BUT, we’ve yet to figure out how to know on http session destroy that it was rewriten, and which one it was.

More precisely, if our wowza gets called with something like http://<server/…/streamA/Manifest,

  1. resolvePlayAlias() gets called with a HTTPStreamerSessionSmoothStreamer object for the httpSession param - we return the rewritten stream name streamB after some checks/validations

  2. onHTTPStreamerSessionCreate() gets called now with the rewritten stream name, BUT with a different httpSession param (and a different ConnectionHolder inside this httpSession) - at this point (and same issue for Destroy) we don’t know that the rewrite was from streamA, and not some other name, or even if it was rewritten.

we tried modifying members inside the httpSession received on resolvePlayAlias() (for instance, modifying the query member to include the original stream name) - but the changes don’t show in the httpSession object we receive on onHTTPStreamerSessionCreate.

of course, without implementing IMediaStreamNameAliasProvider2, nothing else gets called (neither one of onHTTPStreamerSessionCreate, onHTTPSessionCreate or onHTTPSmoothStreamingSessionCreate) as the initial stream name, streamA, is not valid -> so we can’t simply do the rewrite in either of them.

what we need to know is if there is a common/inherited object between the resolvePlayAlias() httpSession object and the one in onHTTPStreamerSessionCreate - anything that can tell us that the second call (onHTTPStreamerSessionCreate, or similar) comes from the same connection/user/whatever as the first call (resolvePlayAlias), so that we can then link this to the streamA-to-streamB rewrite…

…or if there is any other entry point for rewriting the stream name, apart from IMediaStreamNameAliasProvider2

public class qstreamer extends ModuleBase implements IMediaStreamNameAliasProvider2, IHTTPStreamerSessionNotify
{
  public void onAppStart(IApplicationInstance appInstance)
  {
    ...
    appInstance.setStreamNameAliasProvider(this);			
		
    IVHost vhost = appInstance.getVHost();
    HTTPStreamerContext httpStreamerContext = vhost.getHTTPStreamerContext();
    HTTPStreamerSessions httpStreamerSessions = httpStreamerContext.getSessions();
    httpStreamerSessions.addSessionListener(this);
    ...
  }
  public String resolvePlayAlias(IApplicationInstance appInstance, String name, IHTTPStreamerSession [B]httpSession[/B])
  {
    ...
    return streamB;
  }
  public void onHTTPStreamerSessionCreate(IHTTPStreamerSession [B]session[/B])
  {
    // we can't track that this call is made for the same 'client/connection' as the resolve call above as:
    // - [B]session[/B] != [B]httpSession[/B] above
    // - except for the stream name, any changes to [B]httpSession[/B] don't reflect in [B]session[/B]
  }
  public void onHTTPStreamerSessionDestroy(IHTTPStreamerSession [B]session[/B])
  {
  }

}

Hi,

You should find that the sessionID is the same so

httpSession.getSessionId()

I havent tried it, but it should work. You may also find that resolvePlayAlias is called more than once and you should check if appInstance is null ie.

public String resolvePlayAlias(IApplicationInstance appInstance, String name, IHTTPStreamerSession httpSession)
  {
    if ( appInstance == null ) { return name; }
    ...
    return streamB;
  }

I believe the null call is not the one you are after, which may help.

Andrew.

currently for a windows8 stream play call I get:

  • 3 resolve calls - two of them with null sessionID

  • 2 onHTTPStreamerSessionCreate calls - with 2 different sessionIDs between them - one of them being destroyed after a few seconds

all calls have the same appInstance reference

so I can’t use the sessionID…

currently for a windows8 stream play call I get:

  • 3 resolve calls - two of them with null sessionID

  • 2 onHTTPStreamerSessionCreate calls - with 2 different sessionIDs between them - one of them being destroyed after a few seconds

all calls have the same appInstance reference

so I can’t use the sessionID…

Unfortunately I dont have a Windows 8 machine, however in my testing

SmoothStreaming

INFO server comment - Resolve Play HTTPSession: Stream1

INFO server comment - Alias Session ID is ‘null’

INFO smoothstreaming connect 1840855662 -

INFO stream create Stream1 -

INFO server comment - SessionCreate ID is ‘1840855662’

INFO server comment - Resolve Play HTTPSession: Stream1

INFO server comment - Alias Session ID is ‘1840855662’

INFO stream play Stream1 -

CupertinoStreaming

INFO server comment - Resolve Play HTTPSession: Stream1

INFO server comment - Alias Session ID is ‘651934993’

INFO cupertino connect 651934993 -

INFO stream create Stream1 -

INFO server comment - SessionCreate ID is ‘651934993’

INFO server comment - Resolve Play HTTPSession: Stream1

INFO server comment - Alias Session ID is ‘null’

INFO server comment - Resolve Play HTTPSession: Stream1

INFO server comment - Alias Session ID is ‘null’

INFO server comment - Resolve Play HTTPSession: Stream1

INFO server comment - Alias Session ID is ‘null’

INFO server comment - Resolve Play HTTPSession: Stream1

INFO server comment - Alias Session ID is ‘1893651643’

INFO cupertino connect 1893651643 -

INFO stream create Stream1 -

INFO server comment - SessionCreate ID is ‘1893651643’

From Safari 2 connections are always made. I can see that SessionID matches in both the Alias and SessionCreate

The code I used was

package com.wowza.test.aliasHTTP;
import com.wowza.wms.application.*;
import com.wowza.wms.client.*;
import com.wowza.wms.mediacaster.IMediaCaster;
import com.wowza.wms.module.*;
import com.wowza.wms.stream.*;
import com.wowza.wms.stream.livepacketizer.ILiveStreamPacketizer;
import com.wowza.wms.rtp.model.*;
import com.wowza.wms.httpstreamer.model.*;
public class TestSession extends ModuleBase implements IMediaStreamNameAliasProvider2 {
public void onAppStart(IApplicationInstance appInstance) {
		String fullname = appInstance.getApplication().getName() + "/"
				+ appInstance.getName();
		getLogger().info("onAppStart: " + fullname);
		
		appInstance.setStreamNameAliasProvider(this);
	}
	public void onAppStop(IApplicationInstance appInstance) {
		String fullname = appInstance.getApplication().getName() + "/"
				+ appInstance.getName();
		getLogger().info("onAppStop: " + fullname);
	}
	
	public void onHTTPSessionCreate(IHTTPStreamerSession httpSession)
	{
		getLogger().info("SessionCreate ID is '"+httpSession.getSessionId()+"'");
	}
	
	
	public String resolvePlayAlias(IApplicationInstance appInstance,
			String name, IClient client) {
		getLogger().info("Resolve Play Flash: " + name);
		
		return name;
	}
	public String resolvePlayAlias(IApplicationInstance appInstance,
			String name, IHTTPStreamerSession httpSession) {
		getLogger().info("Resolve Play HTTPSession: " + name);
		getLogger().info("Alias Session ID is '"+httpSession.getSessionId()+"'");
			return name;
	}
	public String resolvePlayAlias(IApplicationInstance appInstance,
			String name, RTPSession rtpSession) {
		getLogger().info("Resolve Play RTPSession: " + name);
		return name;
	}
	public String resolvePlayAlias(IApplicationInstance appInstance,
			String name, ILiveStreamPacketizer liveStreamPacketizer) {
		getLogger().info("Resolve Play LiveStreamPacketizer: " + name);
		return name;
	}
	public String resolveStreamAlias(IApplicationInstance appInstance,
			String name, IMediaCaster mediaCaster) {
		getLogger().info("Resolve Stream Mediacaster: " + name);
		return name;
	}
	public String resolvePlayAlias(IApplicationInstance appInstance, String name) {
		getLogger().info("Resolve Play: " + name);
		return name;
	}
	public String resolveStreamAlias(IApplicationInstance appInstance,
			String name) {
		getLogger().info("Resolve Stream: " + name);
		return name;
	}
}

Andrew.