直播弹幕功能实现

引用pom.xml

<dependency>
	<groupId>javax.websocket</groupId>
	<artifactId>javax.websocket-api</artifactId>
	<version>1.1</version>
	<scope>provided</scope>
</dependency>

页面代码index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <meta name="Keywords" content="danmu">
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>弹幕网站</title>
    <style type="text/css">
       /* body {
            background: url(images/01.jpg); no-repeat top center;
            font-size: 12px;
            font-family: "微软雅黑";
        }*/

        * {
            margin: 0;
            padding: 0;
        }
        /* screen start*/
        .screen {
            width: 300px;
            height: 100px;
            background: #669900;
        }


        .dm {
            width: 100%;
            height: 100%;
            position: absolute;
            top: 0;
            left: 0;
            display: none;
        }


        .dm .d_screen .d_del {
            width: 38px;
            height: 38px;
            background: #600;
            display: block;
            text-align: center;
            line-height: 38px;
            text-decoration: none;
            font-size: 20px;
            color: #fff;
            border-radius: 19px;
            border: 1px solid #fff;
            z-index: 2;
            position: absolute;
            right: 20px;
            top: 20px;
            outline: none;
        }


        .dm .d_screen .d_del:hover {
            background: #F00;
        }


        .dm .d_screen .d_mask {
            width: 100%;
            height: 100%;
            background: #000;
            position: absolute;
            top: 0;
            left: 0;
            opacity: 0.6;
            filter: alpha(opacity = 60);
            z-index: 1;
        }


        .dm .d_screen .d_show {
            position: relative;
            z-index: 2;
        }


        .dm .d_screen .d_show div {
            font-size: 26px;
            line-height: 36px;
            font-weight: 500;
            position: absolute;
            top: 76px;
            left: 10;
            color: #fff;
        }
        /*end screen*/


        /*send start*/
        .send {
            width: 100%;
            height: 76px;
            position: absolute;
            bottom: 0;
            left: 0;
            border: 1px solid red;
        }


        .send .s_filter {
            width: 100%;
            height: 76px;
            background: #000;
            position: absolute;
            bottom: 0;
            left: 0;
            opacity: 0.6;
            filter: alpha(opacity = 60);
        }


        .send  .s_con {
            width: 100%;
            height: 76px;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 2;
            text-align: center;
            line-height: 76px;
        }


        .send .s_con .s_text {
            width: 800px;
            height: 36px;
            border: 0;
            border-radius: 6px 0 0 6px;
            outline: none;
        }


        .send .s_con .s_submit {
            width: 100px;
            height: 36px;
            border-radius: 0 6px 6px 0;
            outline: none;
            font-size: 14px;
            color: #fff;
            background: #65c33d;
            font-family: "微软雅黑";
            cursor: pointer;
            border: 1px solid #5bba32;
        }


        .send .s_con .s_submit:hover {
            background: #3eaf0e;
        }
        /*end send*/
    </style>


</head>
<body>
<a href="#" id="startDm">开启弹幕</a>
<!-- dm start -->
<div class="dm">
    <!-- d_screen start -->
    <div class="d_screen">
        <a href="#" class="d_del">X</a>
        <div class="d_mask"></div>
        <div class="d_show">
        </div>
    </div>
    <!-- end d_screen -->
    <!-- send start -->
    <div class="send" style="z-index: 10">
        <div class="s_filter" style="z-index: -1"></div>
        <div class="s_con" >
            <input type="text" class="s_text" /> <input type="button" value="发表评论" class="s_submit" id="btn"/>
        </div>
    </div>
    <!-- end send -->
</div>
<!-- end dm-->
<script type="text/javascript"
        src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.js"></script>
<script type="text/javascript" src="websocket.js">
</script>
<script type="text/javascript">
    $(function() {

        $("#startDm,.d_del").click(function() {
            $("#startDm,.dm").toggle(1000);
//init_screen();
        });
        $("#btn").click(function(){
            send();
        });
        $(".s_text").keydown(function() {
            var code = window.event.keyCode;

            if (code == 13)//回车键按下时,输出到弹幕
            {
                send();
            }
        });
    });

    function launch()
    {
        var _height = $(window).height();
        var _left = $(window).width() - $("#"+index).width();
        var time=10000;
        if(index%2==0)
            time=20000;
        _top+=80;
        if(_top>_height-100)
            _top=80;
        $("#"+index).css({
            left:_left,
            top:_top,
            color:getRandomColor()

        });
        $("#"+index).animate({
                left:"-"+_left+"px"},
            time,
            function(){});
        index++;
    }

    //随机获取颜色值
    function getRandomColor() {
        return '#' + (function(h) {
            return new Array(7 - h.length).join("0") + h
        })((Math.random() * 0x1000000 << 0).toString(16))
    }
</script>

</body>
</html>

websocket.js

var websocket=null;
var _top=80;
var index=0;

var host=window.location.host;
//判断当前浏览器是否支持WebSocket
if('WebSocket' in window){
    websocket=new WebSocket("ws://"+host+"/websocket");
}
else{
    alert("Not Support WebSocket!");
}


//连接发生错误的回调方法
websocket.onerror = function(){
    setMessageInnerHTML("error");
};

//连接成功建立的回调方法
websocket.onopen = function(event){
    setMessageInnerHTML("正在打开弹幕......");
}

//接收到消息的回调方法
websocket.onmessage = function(){
    setMessageInnerHTML(event.data);
}

//连接关闭的回调方法
websocket.onclose = function(){
    setMessageInnerHTML("close");
}


//监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function(){
    websocket.close();
}


//将消息显示在网页上
function setMessageInnerHTML(innerHTML){
    $(".d_show").append("<div id='"+index+"'>"+ innerHTML + "</div>");
    launch();
}


//发送消息
function send(){
    //var message = document.getElementById('text').value;
    var message = $(".s_text").val();
    $(".s_text").val("");
    websocket.send(message);
}

后端代码

package com.shopx5.controller.live;

import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

//每个客户端连接成功的时候在后台都会创建一个相应的MyWebsocket类
@ServerEndpoint("/websocket")
public class LiverWebsocket {
    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
    private static CopyOnWriteArraySet<LiverWebsocket> websocketPools=new CopyOnWriteArraySet<LiverWebsocket>();
    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    /**
          * 连接建立成功调用的方法
          * @param session  可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
          */
    @OnOpen
    public void onOpen(Session session)
    {
        this.session=session;
        websocketPools.add(this);
    }

    @OnClose
    public void onClose()
    {
        websocketPools.remove(this);
    }

    @OnMessage
    public void onMessage(String message,Session session)
    {
        for(LiverWebsocket item:websocketPools)
        {
            try {
                item.send(message);
            } catch (IOException e) {
// TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    private void send(String message) throws IOException{
        this.session.getAsyncRemote().sendText(message);
//this.session.getBasicRemote().sendText(message);
    }
    @OnError
    public void onError(Session session, Throwable error)
    {
        System.out.println("发生错误");
         error.printStackTrace();
    }
}

测试效果在这里插入图片描述

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值