... uses javax.servlet 3.0
... Java EE in Felix looks unpleasant
... it's in the title of the talk
“Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.”-- netty.io
... or a bunch of useful abstractions over the websocket protocol, a request pipeline, etc.
final ServerBootstrap sb = new ServerBootstrap();
sb.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(final SocketChannel ch) throws Exception {
ch.pipeline()
.addLast("dec", new HttpRequestDecoder())
.addLast("agg", new HttpObjectAggregator(65536))
.addLast("enc", new HttpResponseEncoder())
.addLast("auth", slingAuthHandler) // OUR CODE
.addLast("dispatcher", dispatcher); // OUR CODE
}
});
io.netty.handler.codec.http.HttpRequest
⇓
javax.servlet.http.HttpServletRequest
@Reference
private AuthenticationSupport auth;
protected void channelRead0(ChannelHandlerContext ctx, HttpRequest req)
throws Exception {
WrappedNettyHttpRequest authReq = new WrappedNettyHttpRequest(req);
Attribute<ResourceResolver> resolver = ctx.channel().attr(RESOLVER_ATTR_KEY);
//TODO: make sure this won't try to issue redirects via the null response param
if (auth.handleSecurity(authReq, null)) {
LOG.debug("Authentication successful.");
resolver.set((ResourceResolver) authReq.getAttribute(
AuthenticationSupport.REQUEST_ATTRIBUTE_RESOLVER));
} else {
LOG.debug("Authentication failed - using anonymous resolver.");
resolver.set(resourceResolverFactory.getResourceResolver(null));
}
ctx.fireChannelRead(req);
}
RTCAService
: Connection Aggregation ServiceRTCAListener
: Page Edit ListenerOn connect, adds socket to group based on page path.
Exposes groups via getter, used by other services.
... also sends chat status events on connect, disconnect
Sling EventHandler
registered for PageEvents
On modification events, sends list of changed paths to sockets connecting from that page.
Aggregates modification paths since one component edit can yield many changed properties.
var ed = CQ.WCM.getEditable(path);
if (!ed) { return; }
ed.refresh();
// Flash updated component
ed.getEl()
.highlight("ffccaa", {duration: 0.1})
.pause(0.1)
.highlight("ffccaa", {duration: 0.1})
.pause(0.1)
.highlight("ffccaa", {duration: 0.1});
/content/geometrixx/en/jcr:content/par/a/b/c/d