老板怒吼:今晚整一个B站弹幕交互功能

图片来自 包图网

建华网站制作公司哪家好,找创新互联公司!从网页设计、网站建设、微信开发、APP开发、自适应网站建设等网站项目制作,到程序开发,运营维护。创新互联公司于2013年创立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联公司

今天笔者就抽空做了一个实时视频弹幕交互的小功能,不得不说这样的形式为看视频看直播,讲义 PPT,抽奖等形式增加了许多乐趣。

技术选型

①Netty

官方对于 Netty 的描述:

 
 
 
 
  1. https://netty.io/ 

主要关键词描述:Netty 是异步事件驱动网络框架,可做各种协议服务端,并且支持了 FTP,SMTP,HTTP 等很多协议,并且性能,稳定性,灵活性都很棒。

可以看到 Netty 整体架构上分了三个部分:

  • 以零拷贝,一致性接口,扩展事件模型的底层核心。
  • Socket,Datagram,Pipe,Http Tunnel 作为传输媒介。
  • 传输支持的各种协议,HTTP&WebSocket,SSL,大文件,zlib/gzip 压缩,文本,二进制,Google Protobuf 等各种各种的传输形式。

②WebSocket

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。WebSocket 通信协议于 2011 年被 IETF 定为标准 RFC 6455,并由 RFC7936 补充规范。

WebSocket API 也被 W3C 定为标准。WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。

在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

为什么做这样的技术选型:

  • 由上述可知,实时直播交互作为互动式是一个双向数据传输过程。所以使用 WebSocket。
  • Netty 本身支持了 WebSocket 协议的实现,让实现更加简单方便。

实现思路

①服务架构

整体架构是所有客户端都和我的服务端开启一个双向通道的架构。

②传输流程

如下图:

实现效果

先看看效果吧,是不是 perfect,接下来就来看具体代码是怎么实现的吧。

视频直播弹幕示例

代码实现

①项目结构

一个 maven 项目,将代码放一个包下就行。

②Java 服务端

Java 服务端代码,总共三个类,Server,Initailizer 和 Handler。

先做一个 netty nio 的服务端:一个 nio 的服务,开启一个 tcp 端口。

 
 
 
 
  1. import io.netty.bootstrap.ServerBootstrap; 
  2. import io.netty.channel.ChannelFuture; 
  3. import io.netty.channel.EventLoopGroup; 
  4. import io.netty.channel.nio.NioEventLoopGroup; 
  5. import io.netty.channel.socket.nio.NioServerSocketChannel; 
  6.  
  7. /** 
  8.  * Copyright(c)lbhbinhao@163.com 
  9.  * @author liubinhao 
  10.  * @date 2021/1/14 
  11.  * ++++ ______                           ______             ______ 
  12.  * +++/     /|                         /     /|           /     /| 
  13.  * +/_____/  |                       /_____/  |         /_____/  | 
  14.  * |     |   |                      |     |   |        |     |   | 
  15.  * |     |   |                      |     |   |________|     |   | 
  16.  * |     |   |                      |     |  /         |     |   | 
  17.  * |     |   |                      |     |/___________|     |   | 
  18.  * |     |   |___________________   |     |____________|     |   | 
  19.  * |     |  /                  / |  |     |   |        |     |   | 
  20.  * |     |/ _________________/  /   |     |  /         |     |  / 
  21.  * |_________________________|/b    |_____|/           |_____|/ 
  22.  */ 
  23. public enum BulletChatServer { 
  24.     /** 
  25.      * Server instance 
  26.      */ 
  27.     SERVER; 
  28.  
  29.     private BulletChatServer(){ 
  30.         EventLoopGroup mainGroup = new NioEventLoopGroup(); 
  31.         EventLoopGroup subGroup  = new NioEventLoopGroup(); 
  32.         ServerBootstrap server = new ServerBootstrap(); 
  33.         server.group(mainGroup,subGroup) 
  34.                 .channel(NioServerSocketChannel.class) 
  35.                 .childHandler(new BulletChatInitializer()); 
  36.         ChannelFuture future = server.bind(9123); 
  37.     } 
  38.  
  39.     public static void main(String[] args) { 
  40.  
  41.     } 
  42.  

服务端的具体处理逻辑:

 
 
 
 
  1. import io.netty.channel.ChannelInitializer; 
  2. import io.netty.channel.ChannelPipeline; 
  3. import io.netty.channel.socket.SocketChannel; 
  4. import io.netty.handler.codec.http.HttpObjectAggregator; 
  5. import io.netty.handler.codec.http.HttpServerCodec; 
  6. import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; 
  7. import io.netty.handler.stream.ChunkedWriteHandler; 
  8. import io.netty.handler.timeout.IdleStateHandler; 
  9.  
  10. /** 
  11.  * Copyright(c)lbhbinhao@163.com 
  12.  * 
  13.  * @author liubinhao 
  14.  * @date 2021/1/14 
  15.  * ++++ ______                           ______             ______ 
  16.  * +++/     /|                         /     /|           /     /| 
  17.  * +/_____/  |                       /_____/  |         /_____/  | 
  18.  * |     |   |                      |     |   |        |     |   | 
  19.  * |     |   |                      |     |   |________|     |   | 
  20.  * |     |   |                      |     |  /         |     |   | 
  21.  * |     |   |                      |     |/___________|     |   | 
  22.  * |     |   |___________________   |     |____________|     |   | 
  23.  * |     |  /                  / |  |     |   |        |     |   | 
  24.  * |     |/ _________________/  /   |     |  /         |     |  / 
  25.  * |_________________________|/b    |_____|/           |_____|/ 
  26.  */ 
  27.  
  28. public class BulletChatInitializer extends ChannelInitializer { 
  29.     @Override 
  30.     protected void initChannel(SocketChannel ch) throws Exception { 
  31.         ChannelPipeline pipeline = ch.pipeline(); 
  32.         pipeline.addLast(new HttpServerCodec()); 
  33.         pipeline.addLast(new ChunkedWriteHandler()); 
  34.         pipeline.addLast(new HttpObjectAggregator(1024*64)); 
  35.         pipeline.addLast(new IdleStateHandler(8, 10, 12)); 
  36.         pipeline.addLast(new WebSocketServerProtocolHandler("/lbh")); 
  37.         pipeline.addLast(new BulletChatHandler()); 
  38.     } 

后台处理逻辑,接受到消息,写出到所有的客户端:

 
 
 
 
  1. import io.netty.channel.Channel; 
  2. import io.netty.channel.ChannelHandler; 
  3. import io.netty.channel.ChannelHandlerContext; 
  4. import io.netty.channel.SimpleChannelInboundHandler; 
  5. import io.netty.channel.group.ChannelGroup; 
  6. import io.netty.channel.group.DefaultChannelGroup; 
  7. import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; 
  8. import io.netty.util.concurrent.EventExecutorGroup; 
  9. import io.netty.util.concurrent.GlobalEventExecutor; 
  10.  
  11. /** 
  12.  * Copyright(c)lbhbinhao@163.com 
  13.  * 
  14.  * @author liubinhao 
  15.  * @date 2021/1/14 
  16.  * ++++ ______                           ______             ______ 
  17.  * +++/     /|                         /     /|           /     /| 
  18.  * +/_____/  |                       /_____/  |         /_____/  | 
  19.  * |     |   |                      |     |   |        |     |   | 
  20.  * |     |   |                      |     |   |________|     |   | 
  21.  * |     |   |                      |     |  /         |     |   | 
  22.  * |     |   |                      |     |/___________|     |   | 
  23.  * |     |   |___________________   |     |____________|     |   | 
  24.  * |     |  /                  / |  |     |   |        |     |   | 
  25.  * |     |/ _________________/  /   |     |  /         |     |  / 
  26.  * |_________________________|/b    |_____|/           |_____|/ 
  27.  */ 
  28.  
  29. public class BulletChatHandler  extends SimpleChannelInboundHandler { 
  30.     // 用于记录和管理所有客户端的channel 
  31.     public static ChannelGroup channels = 
  32.             new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); 
  33.     @Override 
  34.     protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception { 
  35.         // 获取客户端传输过来的消息 
  36.         String content = msg.text(); 
  37.         System.err.println("收到消息:"+ content); 
  38.         channels.writeAndFlush(new TextWebSocketFrame(content)); 
  39.         System.err.println("写出消息完成:"+content); 
  40.     } 
  41.  
  42.     @Override 
  43.     public void handlerAdded(ChannelHandlerContext ctx) throws Exception { 
  44.         channels.add(ctx.channel()); 
  45.     } 
  46.  
  47.     @Override 
  48.     public void handlerRemoved(ChannelHandlerContext ctx) throws Exception { 
  49.  
  50.         String channelId = ctx.channel().id().asShortText(); 
  51.         System.out.println("客户端被移除,channelId为:" + channelId); 
  52.         channels.remove(ctx.channel()); 
  53.     } 
  54.  
  55.     @Override 
  56.     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 
  57.         cause.printStackTrace(); 
  58.         // 发生异常之后关闭连接(关闭channel),随后从ChannelGroup中移除 
  59.         ctx.channel().close(); 
  60.         channels.remove(ctx.channel()); 
  61.     } 
  62.  

③网页客户端实现

代码如下:

 
 
 
 
  1.  
  2.  
  3.  
  4.      
  5.      
  6.     Netty视频弹幕实现 Author:Binhao Liu 
  7.      
  8.      
  9.         * { 
  10.             margin: 0px; 
  11.             padding: 0px 
  12.         } 
  13.  
  14.         html, body { 
  15.             height: 100% 
  16.         } 
  17.  
  18.         body { 
  19.             overflow: hidden; 
  20.             background-color: #FFF; 
  21.             text-align: center; 
  22.         } 
  23.  
  24.         .flex-column { 
  25.             display: flex; 
  26.             flex-direction: column; 
  27.             justify-content: space-between;, align-items: center; 
  28.         } 
  29.  
  30.         .flex-row { 
  31.             display: flex; 
  32.             flex-direction: row; 
  33.             justify-content: center; 
  34.             align-items: center; 
  35.         } 
  36.  
  37.         .wrap { 
  38.             overflow: hidden; 
  39.             width: 70%; 
  40.             height: 600px; 
  41.             margin: 100px auto; 
  42.             padding: 20px; 
  43.             background-color: transparent; 
  44.             box-shadow: 0 0 9px #222; 
  45.             border-radius: 20px; 
  46.         } 
  47.  
  48.         .wrap .box { 
  49.             position: relative; 
  50.             width: 100%; 
  51.             height: 90%; 
  52.             background-color: #000000; 
  53.             border-radius: 10px 
  54.         } 
  55.  
  56.         .wrap .box span { 
  57.             position: absolute; 
  58.             top: 10px; 
  59.             left: 20px; 
  60.             display: block; 
  61.             padding: 10px; 
  62.             color: #336688 
  63.         } 
  64.  
  65.         .wrap .send { 
  66.             display: flex; 
  67.             width: 100%; 
  68.             height: 10%; 
  69.             background-color: #000000; 
  70.             border-radius: 8px 
  71.         } 
  72.  
  73.         .wrap .send input { 
  74.             width: 40%; 
  75.             height: 60%; 
  76.             border: 0; 
  77.             outline: 0; 
  78.             border-radius: 5px 0px 0px 5px; 
  79.             box-shadow: 0px 0px 5px #d9d9d9; 
  80.             text-indent: 1em 
  81.         } 
  82.  
  83.         .wrap .send .send-btn { 
  84.             width: 100px; 
  85.             height: 60%; 
  86.             background-color: #fe943b; 
  87.             color: #FFF; 
  88.             text-align: center; 
  89.             border-radius: 0px 5px 5px 0px; 
  90.             line-height: 30px; 
  91.             cursor: pointer; 
  92.         } 
  93.  
  94.         .wrap .send .send-btn:hover { 
  95.             background-color: #4cacdc 
  96.         } 
  97.      
  98.  
  99.  
  100.  
  101.  
  102.      
  103.          
  104.     
 
  •      
  •  
  •          
  •  
  •         发送
  •  
  •     
  •  
  •  
  •  
  •  
  •  
  •  
  • 这样一个实时的视频弹幕功能就完成啦,是不是很简单,各位小伙伴快来试试吧。

    小结

    这个还是很简单,笔者写这个的时候一会儿就写完了。不过这也得益于笔者很久以前就写过 Netty 的服务,对于 HTTP,TCP 之类协议也比较熟悉。

    只有前端会有些难度,问下度娘,也很快能做完,在此分享出来与诸君分享,有问题可找笔者交流。

    作者:兴趣使然的程序猿

    编辑:陶家龙

    出处:http://adkx.net/w71wf

    分享名称:老板怒吼:今晚整一个B站弹幕交互功能
    路径分享:http://www.shufengxianlan.com/qtweb/news20/275270.html

    网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

    广告

    声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

    猜你还喜欢下面的内容

    企业建站知识

    同城分类信息