婚庆现场或年会上有在大屏上一直滚动的视频,来宾关注公众号后就可以直接发送留言上墙了,看起来貌似好好玩的样子
弹幕一般利用websocket和后台server建立连接然后发送/接收数据,这里使用H5来做前台页面,只是一个demo没有做过多的美化和优化,特别是server端代码,一旦信息多了会撑爆内存,如果需要在实际中使用还需进一步处理。
前台展示主要用到了websocket,基本上看源码就能明白,核心代码如下:
<script>
//WebSocket
var wsServer = 'ws://172.17.154.228:7181';
var websocket= new WebSocket(wsServer);
websocket.onopen = function (evt) {
console.log("Connected to WebSocket server.");
/*websocket.send("gaga");*/
//连上之后就打开弹幕
$('#danmu').danmu('danmuResume');
};
websocket.onclose = function (evt) {
console.log("Disconnected");
};
websocket.onmessage = function (evt) {
console.log('Retrieved data from server: ' + evt.data);
var time = $('#danmu').data("nowTime")+1;
var text_obj = evt.data.indexOf("time") == -1 ? evt.data + ',"time":' + time + '}' : evt.data;//获取加上当前时间
console.log(text_obj);
var new_obj = eval('(' + text_obj + ')');
$('#danmu').danmu("addDanmu",new_obj);//添加弹幕
};
websocket.onerror = function (evt, e) {
console.log('Error occured: ' + evt.data);
};
//初始化
$("#danmu").danmu({
left:0,
top:0,
height:"100%",
width:"100%",
speed:20000,
opacity:1,
font_size_small:16,
font_size_big:24,
top_botton_danmu_time:6000
});
//一个定时器,监视弹幕时间并更新到页面上
function timedCount(){
$("#time").text($('#danmu').data("nowTime"));
t=setTimeout("timedCount()",50)
}
timedCount();
function starter(){
$('#danmu').danmu('danmuStart');
}
function pauser(){
$('#danmu').danmu('danmuPause');
}
function resumer(){
$('#danmu').danmu('danmuResume');
}
function stoper(){
$('#danmu').danmu('danmuStop');
}
function getime(){
alert($('#danmu').data("nowTime"));
}
function getpaused(){
alert($('#danmu').data("paused"));
}
//发送弹幕,使用了文档README.md第7节中推荐的方法
function send(){
var text = document.getElementById('text').value;
var color = document.getElementById('color').value;
var position = document.getElementById('position').value;
var time = $('#danmu').data("nowTime")+1;
var size =document.getElementById('text_size').value;
var text_obj='{ "text":"'+text+'","color":"'+color+'","size":"'+size+'","position":"'+position+'","time":'+time+'}';
//为了处理简单,方便后续加time,和isnew,就先酱紫发一半吧。
//注:time为弹幕出来的时间,isnew为是否加边框,自己发的弹幕,常理上来说是有边框的。
//var text_obj='{ "text":"'+text+'","color":"'+color+'","size":"'+size+'","position":"'+position+'"';
//利用websocket发送
websocket.send(text_obj);
//清空相应的内容
document.getElementById('text').value='';
}
//调整透明度函数
function op(){
var op=document.getElementById('op').value;
$('#danmu').danmu("setOpacity",op/100);
}
//调隐藏 显示
function changehide() {
var op = document.getElementById('op').value;
op = op / 100;
if (document.getElementById("ishide").checked) {
$("#danmu").danmu("setOpacity",1)
} else {
$("#danmu").danmu("setOpacity",0)
}
}
//设置弹幕时间
function settime(){
var t=document.getElementById("set_time").value;
t=parseInt(t)
$('#danmu').danmu("setTime",t);
}
</script>
在服务端保存每个进来的连接,然后将接收到的消息分发出去
server.Start(socket =>
{
socket.OnOpen = () =>
{
Console.WriteLine("Open!");
foreach(string msg in readBuffer)
{
socket.Send(msg);
}
allSockets.Add(socket);
};
socket.OnClose = () =>
{
Console.WriteLine("Close!");
allSockets.Remove(socket);
if (allSockets.Count == 0)
{
StreamWriter sw = new StreamWriter(recordPath);
foreach (string msg in readBuffer)
sw.WriteLine(msg);
sw.Close();
}
};
socket.OnMessage = message =>
{
Console.WriteLine(message);
readBuffer.Add(message);
allSockets.ToList().ForEach(s => s.Send(message.Substring(0,message.LastIndexOf(','))));
};
socket.OnBinary = file => {
string path = ("D:\\test.txt");
//创建一个文件流
FileStream fs = new FileStream(path, FileMode.Create);
//将byte数组写入文件中
fs.Write(file, 0, file.Length);
fs.Close();
};
});
var input = Console.ReadLine();
while (input != "exit")
{
foreach (var socket in allSockets.ToList())
{
socket.Send(input);
}
input = Console.ReadLine();
}
附加:源码传送门