Real-Time Video Bullet Chat Implementation Using Netty and WebSocket
This article demonstrates how to build a real‑time video bullet‑chat system by selecting Netty and WebSocket, designing a bidirectional service architecture, implementing a Java server with Netty handlers, and creating a browser client with HTML5 video and JavaScript to send and display scrolling comments.
In 2021, the author noticed the growing popularity of bullet‑chat features on video platforms and decided to implement a real‑time interactive bullet‑chat system for video, live streaming, PPT, and other use cases.
1. Technology Selection
The core technologies chosen are Netty , an asynchronous event‑driven network framework that supports many protocols (FTP, SMTP, HTTP, etc.), and WebSocket , a full‑duplex communication protocol standardized by RFC 6455, which simplifies bidirectional data exchange between client and server.
Netty is used because it already provides a robust implementation of the WebSocket protocol, making the development process easier.
2. Implementation Idea
The overall architecture establishes a persistent two‑way channel between every client and the server, enabling real‑time message broadcasting.
2.1 Service Architecture
All clients connect to a Netty NIO server that listens on a TCP port (e.g., 9123) and upgrades the connection to WebSocket.
2.2 Transmission Process
Messages sent from any client are received by the server and then broadcast to all connected clients.
3. Implementation Effect
The author shows a screenshot of the video with scrolling bullet comments, confirming the functionality.
4. Code Implementation
4.1 Project Structure
A simple Maven project containing all Java classes under a single package.
4.2 Java Server
Three main classes are provided: BulletChatServer , BulletChatInitializer , and BulletChatHandler .
public enum BulletChatServer {
SERVER;
private BulletChatServer() {
EventLoopGroup mainGroup = new NioEventLoopGroup();
EventLoopGroup subGroup = new NioEventLoopGroup();
ServerBootstrap server = new ServerBootstrap();
server.group(mainGroup, subGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new BulletChatInitializer());
ChannelFuture future = server.bind(9123);
}
public static void main(String[] args) { }
}The initializer configures the pipeline with HTTP codec, chunked writer, aggregator, idle state handler, WebSocket protocol handler, and the custom BulletChatHandler :
public class BulletChatInitializer extends ChannelInitializer
{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new ChunkedWriteHandler());
pipeline.addLast(new HttpObjectAggregator(1024*64));
pipeline.addLast(new IdleStateHandler(8,10,12));
pipeline.addLast(new WebSocketServerProtocolHandler("/lbh"));
pipeline.addLast(new BulletChatHandler());
}
}The handler maintains a ChannelGroup of all client channels and forwards received TextWebSocketFrame messages to every client:
public class BulletChatHandler extends SimpleChannelInboundHandler
{
public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
String content = msg.text();
channels.writeAndFlush(new TextWebSocketFrame(content));
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception { channels.add(ctx.channel()); }
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { channels.remove(ctx.channel()); }
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { ctx.close(); channels.remove(ctx.channel()); }
}4.3 Web Client
The front‑end consists of an HTML page with a video element and a text input for sending comments. JavaScript creates a WebSocket connection to ws://localhost:9123/lbh , sends messages, and renders incoming comments as moving <span> elements over the video.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Netty Video Bullet Chat</title>
<style>/* CSS omitted for brevity */</style>
</head>
<body>
<div class="wrap flex-column">
<div class="box">
<video src="shape.mp4" width="100%" height="100%" controls autoplay></video>
</div>
<div class="send flex-row">
<input type="text" class="con" placeholder="弹幕发送[]~(^v^)~*"/>
<div class="send-btn" onclick="sendMsg(document.querySelector('.con').value)">发送</div>
</div>
</div>
<script>
var ws = new WebSocket("ws://localhost:9123/lbh");
ws.onopen = function(){ alert("数据发送中..."); };
ws.onmessage = function(e){ createEle(e.data); };
ws.onclose = function(){ alert("连接已关闭..."); };
function sendMsg(msg){ ws.send(msg); }
// Functions createEle, roll, random, etc. omitted for brevity
</script>
</body>
</html>5. Summary
The author completed the real‑time bullet‑chat feature quickly thanks to prior experience with Netty and networking protocols. The solution combines a lightweight Netty WebSocket server with a simple HTML5/JavaScript client, making it easy to integrate into video, live‑stream, or PPT applications.
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.