Initializing WebSockets For a Red5pro Application
Websockets can be enabled for a Red5pro application through its Application adapter class. The recommended way of doing this is to register websocket for the application in the appStart
handler and remove it using the appStop
handler. The code snippet given below shows how the Application adapter
of the chat application is used for registering and unregistering with the websocket plugin.
public class Application extends MultiThreadedApplicationAdapter implements ApplicationContextAware {
private static Logger log = Red5LoggerFactory.getLogger(Application.class, "chat");
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public boolean appStart(IScope scope) {
log.info("Chat starting");
configureApplicationScopeWebSocket(scope);
return super.appStart(scope);
}
@Override
public void appStop(IScope scope) {
log.info("Chat stopping");
// remove our app
WebSocketScopeManager manager = ((WebSocketPlugin) PluginRegistry.getPlugin("WebSocketPlugin")).getManager(scope);
manager.removeApplication(scope);
manager.stop();
}
/**
* Configures a websocket scope for a given application scope.
*
* @param scope Server application scope
*/
private void configureApplicationScopeWebSocket(IScope scope) {
// first get the websocket plugin
WebSocketPlugin wsPlugin = ((WebSocketPlugin) PluginRegistry.getPlugin(WebSocketPlugin.NAME));
// get the websocket scope manager for the red5 scope
WebSocketScopeManager manager = wsPlugin.getManager(scope);
if (manager == null) {
// get the application adapter
MultiThreadedApplicationAdapter app = (MultiThreadedApplicationAdapter) scope.getHandler();
log.debug("Creating WebSocketScopeManager for {}", app);
// set the application in the plugin to create a websocket scope manager for it
wsPlugin.setApplication(app);
// get the new manager
manager = wsPlugin.getManager(scope);
}
// the websocket scope
WebSocketScope wsScope = (WebSocketScope) scope.getAttribute(WSConstants.WS_SCOPE);
// check to see if its already configured
if (wsScope == null) {
log.debug("Configuring application scope: {}", scope);
// create a websocket scope for the application
wsScope = new WebSocketScope(scope);
// register the ws scope
wsScope.register();
}
}
}
Once the application is registered with the websocket plugin, the next step is to create your websocket handler class, extending the org.red5.net.websocket.listener.WebSocketDataListener
class. This class will handle the standard server side websocket events for the clients. An example of the implementation would be the WebSocketChatDataListener.java class.
Finally we tell the application to use this WebSocketDataListener
implementation to handle all websocket requests to our Red5pro application. This is done by adding a Bean definition to the context file (red5-web.xml
) of the Red5pro application.
If you look at the Red5 red5-web.xml
file of the red5 websocket chat sample application, you will see how a reference of the Red5 application is made available to the websocket listener via the virtual router (Router.java) using spring bean configuration.
<bean id="web.handler" class="org.red5.demos.chat.Application" />
<bean id="router" class="org.red5.demos.chat.Router">
<property name="app" ref="web.handler" />
</bean>
<!-- WebSocket scope with our listeners -->
<bean id="webSocketScopeDefault" class="org.red5.net.websocket.WebSocketScope" lazy-init="true">
<!-- Application scope -->
<constructor-arg ref="web.scope" />
<!-- The ws scope listeners -->
<property name="listeners">
<list>
<bean id="chatListener" class="org.red5.demos.chat.WebSocketChatDataListener">
<property name="router" ref="router" />
</bean>
</list>
</property>
</bean>
Websocket filter
Lastly, the websocket filter must be added to each web application that will act as a websocket end point. In the webapp descriptor webapps/myapp/WEB-INF/web.xml
add this entry alongside any other filters or servlets.
<!-- WebSocket filter -->
<filter>
<filter-name>WebSocketFilter</filter-name>
<filter-class>org.red5.net.websocket.server.WsFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>WebSocketFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
To support subprotocols, add them as a comma-delimited string in the web.xml
:
<!-- WebSocket subprotocols -->
<context-param>
<param-name>subProtocols</param-name>
<param-value>chat,json</param-value>
</context-param>
The plugin will default to allowing any requested subprotocol if none are specified.
You can use this to form a means of communication between your Red5 application adapter and WebSocket data listener classes.