mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-09-27 03:25:56 +08:00
修复集群传输bug
This commit is contained in:
@@ -1 +1 @@
|
|||||||
#app,body,html{height:100%}#app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#184c18;position:relative}#app>div:first-child{position:absolute;top:10px;left:30px;font-size:x-large}.content{padding-top:60px}.feature-title[data-v-54efad41]{color:#eb5e46;font-weight:700;font-size:larger}p[data-v-54efad41]{margin:30px;font-size:20px}img[data-v-54efad41]{margin:20px}.root[data-v-e34eab40]{background:#d3d3d3}.root>img[data-v-e34eab40]{width:300px;margin:30px}.records[data-v-4eee1624]{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:0 15px}.records>[data-v-4eee1624]{width:200px}.log-container{overflow-y:auto;max-height:500px}@-webkit-keyframes recording-data-v-f6113870{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}@keyframes recording-data-v-f6113870{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}.recording[data-v-f6113870]{-webkit-animation:recording-data-v-f6113870 1s infinite;animation:recording-data-v-f6113870 1s infinite}.layout[data-v-f6113870]{padding-bottom:30px;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.room[data-v-f6113870]{width:250px;margin:10px;text-align:left}.empty[data-v-f6113870]{color:#eb5e46;width:100%;min-height:500px;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.empty[data-v-f6113870],.status[data-v-f6113870]{display:-webkit-box;display:-ms-flexbox;display:flex}.status[data-v-f6113870]{position:fixed;left:5px;bottom:10px}.status>div[data-v-f6113870]{margin:0 5px}
|
#app,body,html{height:100%}#app{font-family:Avenir,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-align:center;color:#184c18;position:relative}#app>div:first-child{position:absolute;top:10px;left:30px;font-size:x-large}.content{padding-top:60px}.feature-title[data-v-54efad41]{color:#eb5e46;font-weight:700;font-size:larger}p[data-v-54efad41]{margin:30px;font-size:20px}img[data-v-54efad41]{margin:20px}.root[data-v-e34eab40]{background:#d3d3d3}.root>img[data-v-e34eab40]{width:300px;margin:30px}.records[data-v-7d5ab110]{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:0 15px}.records>[data-v-7d5ab110]{width:200px}.log-container{overflow-y:auto;max-height:500px}@-webkit-keyframes recording-data-v-65ac4b48{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}@keyframes recording-data-v-65ac4b48{0%{opacity:.2}50%{opacity:1}to{opacity:.2}}.recording[data-v-65ac4b48]{-webkit-animation:recording-data-v-65ac4b48 1s infinite;animation:recording-data-v-65ac4b48 1s infinite}.layout[data-v-65ac4b48]{padding-bottom:30px;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.room[data-v-65ac4b48]{width:250px;margin:10px;text-align:left}.empty[data-v-65ac4b48]{color:#eb5e46;width:100%;min-height:500px;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.empty[data-v-65ac4b48],.status[data-v-65ac4b48]{display:-webkit-box;display:-ms-flexbox;display:flex}.status[data-v-65ac4b48]{position:fixed;left:5px;bottom:10px}.status>div[data-v-65ac4b48]{margin:0 5px}
|
2
dashboard/dist/index.html
vendored
2
dashboard/dist/index.html
vendored
@@ -1 +1 @@
|
|||||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title>Monibuca</title><script src=jessibuca/ajax.js></script><script src=jessibuca/renderer.js></script><link href=/css/app.ea4656d8.css rel=preload as=style><link href=/css/chunk-vendors.22ebf426.css rel=preload as=style><link href=/js/app.0267da57.js rel=preload as=script><link href=/js/chunk-vendors.ebc28a73.js rel=preload as=script><link href=/css/chunk-vendors.22ebf426.css rel=stylesheet><link href=/css/app.ea4656d8.css rel=stylesheet></head><body><noscript><strong>We're sorry but dashboard doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.ebc28a73.js></script><script src=/js/app.0267da57.js></script></body></html>
|
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title>Monibuca</title><script src=jessibuca/ajax.js></script><script src=jessibuca/renderer.js></script><link href=/css/app.ce470878.css rel=preload as=style><link href=/css/chunk-vendors.22ebf426.css rel=preload as=style><link href=/js/app.017fb959.js rel=preload as=script><link href=/js/chunk-vendors.ebc28a73.js rel=preload as=script><link href=/css/chunk-vendors.22ebf426.css rel=stylesheet><link href=/css/app.ce470878.css rel=stylesheet></head><body><noscript><strong>We're sorry but dashboard doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.ebc28a73.js></script><script src=/js/app.017fb959.js></script></body></html>
|
2
dashboard/dist/js/app.017fb959.js
vendored
Normal file
2
dashboard/dist/js/app.017fb959.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
dashboard/dist/js/app.017fb959.js.map
vendored
Normal file
1
dashboard/dist/js/app.017fb959.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
dashboard/dist/js/app.0267da57.js
vendored
2
dashboard/dist/js/app.0267da57.js
vendored
File diff suppressed because one or more lines are too long
1
dashboard/dist/js/app.0267da57.js.map
vendored
1
dashboard/dist/js/app.0267da57.js.map
vendored
File diff suppressed because one or more lines are too long
@@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="mountNode"></div>
|
<div>
|
||||||
|
自动更新
|
||||||
|
<i-switch v-model="autoUpdate"></i-switch>
|
||||||
|
<div id="mountNode"></div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -7,24 +11,22 @@ import { mapState } from "vuex";
|
|||||||
import G6 from "@antv/g6";
|
import G6 from "@antv/g6";
|
||||||
var graph = null;
|
var graph = null;
|
||||||
export default {
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
autoUpdate: true
|
||||||
|
};
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
data(state) {
|
data(state) {
|
||||||
let summary = state.summary;
|
let d = this.addServer(state.summary);
|
||||||
// 点集
|
d.label = "🏠" + d.label;
|
||||||
let nodes = [];
|
return d;
|
||||||
// 边集
|
|
||||||
let edges = [];
|
|
||||||
this.addServer(summary, nodes, edges);
|
|
||||||
return {
|
|
||||||
nodes,
|
|
||||||
edges
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
addServer(node, nodes, edges) {
|
addServer(node) {
|
||||||
let result = {
|
let result = {
|
||||||
id: node.Address,
|
id: node.Address,
|
||||||
label: node.Address,
|
label: node.Address,
|
||||||
@@ -33,61 +35,69 @@ export default {
|
|||||||
shape: "modelRect",
|
shape: "modelRect",
|
||||||
logoIcon: {
|
logoIcon: {
|
||||||
show: false
|
show: false
|
||||||
}
|
},
|
||||||
|
children: []
|
||||||
};
|
};
|
||||||
nodes.push(result);
|
|
||||||
if (node.Rooms) {
|
if (node.Rooms) {
|
||||||
for (let i = 0; i < node.Rooms.length; i++) {
|
for (let i = 0; i < node.Rooms.length; i++) {
|
||||||
let room = node.Rooms[i];
|
let room = node.Rooms[i];
|
||||||
let roomId = result.id + room.StreamPath;
|
let roomId = room.StreamPath;
|
||||||
nodes.push({
|
let roomData = {
|
||||||
id: roomId,
|
id: roomId,
|
||||||
label: room.StreamPath,
|
label: room.StreamPath,
|
||||||
shape: "rect"
|
shape: "rect",
|
||||||
});
|
children: []
|
||||||
edges.push({ source: result.id, target: roomId });
|
};
|
||||||
|
result.children.push(roomData);
|
||||||
if (room.SubscriberInfo) {
|
if (room.SubscriberInfo) {
|
||||||
for (let j = 0; j < room.SubscriberInfo.length; j++) {
|
for (let j = 0; j < room.SubscriberInfo.length; j++) {
|
||||||
let subId = roomId + room.SubscriberInfo[j].ID;
|
let subId = roomId + room.SubscriberInfo[j].ID;
|
||||||
nodes.push({
|
roomData.children.push({
|
||||||
id: subId,
|
id: subId,
|
||||||
label: room.SubscriberInfo[j].ID
|
label: room.SubscriberInfo[j].ID
|
||||||
});
|
});
|
||||||
edges.push({ source: roomId, target: subId });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node.Children) {
|
if (node.Children) {
|
||||||
for (let childId in node.Children) {
|
for (let childId in node.Children) {
|
||||||
this.addServer(node.Children[childId], nodes, edges);
|
result.children.push(this.addServer(node.Children[childId]));
|
||||||
edges.push({
|
|
||||||
source: result.id,
|
|
||||||
target: childId
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
data(v) {
|
data(v) {
|
||||||
if (graph) {
|
if (graph && this.autoUpdate) {
|
||||||
graph.read(v); // 加载数据
|
//graph.updateChild(v, "");
|
||||||
|
graph.changeData(v); // 加载数据
|
||||||
|
graph.fitView();
|
||||||
|
//graph.read(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
graph = new G6.Graph({
|
graph = new G6.TreeGraph({
|
||||||
renderer: "svg",
|
linkCenter: true,
|
||||||
|
// renderer: "svg",
|
||||||
container: "mountNode", // 指定挂载容器
|
container: "mountNode", // 指定挂载容器
|
||||||
width: 800, // 图的宽度
|
width: 800, // 图的宽度
|
||||||
height: 500, // 图的高度
|
height: 500, // 图的高度
|
||||||
layout: {
|
modes: {
|
||||||
type: "radial"
|
default: ["drag-canvas", "zoom-canvas", "click-select", "drag-node"]
|
||||||
},
|
},
|
||||||
defaultNode: {}
|
animate: false,
|
||||||
|
layout: {
|
||||||
|
// type: "indeted",
|
||||||
|
direction: "H"
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
//graph.addChild(this.data, "");
|
||||||
graph.read(this.data); // 加载数据
|
graph.read(this.data); // 加载数据
|
||||||
|
graph.fitView();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@@ -33,7 +33,7 @@ export default {
|
|||||||
x => {
|
x => {
|
||||||
if (x == "success") {
|
if (x == "success") {
|
||||||
this.onVisible(true);
|
this.onVisible(true);
|
||||||
this.$Message.success("删除成功");
|
this.$Message.success("开始发布");
|
||||||
} else {
|
} else {
|
||||||
this.$Message.error(x);
|
this.$Message.error(x);
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ export default {
|
|||||||
{ streamPath: item.Path.replace(".flv", "") },
|
{ streamPath: item.Path.replace(".flv", "") },
|
||||||
x => {
|
x => {
|
||||||
if (x == "success") {
|
if (x == "success") {
|
||||||
this.$Message.success("开始发布");
|
this.$Message.success("删除成功");
|
||||||
} else {
|
} else {
|
||||||
this.$Message.error(x);
|
this.$Message.error(x);
|
||||||
}
|
}
|
||||||
|
@@ -118,6 +118,7 @@ export default {
|
|||||||
currentTab: "",
|
currentTab: "",
|
||||||
currentStream: [],
|
currentStream: [],
|
||||||
typeMap: {
|
typeMap: {
|
||||||
|
Receiver: "📡",
|
||||||
FlvFile: "🎥",
|
FlvFile: "🎥",
|
||||||
TS: "🎬",
|
TS: "🎬",
|
||||||
HLS: "🍎",
|
HLS: "🍎",
|
||||||
|
@@ -3,12 +3,14 @@ package cluster
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
|
||||||
. "github.com/langhuihui/monibuca/monica"
|
. "github.com/langhuihui/monibuca/monica"
|
||||||
"github.com/langhuihui/monibuca/monica/avformat"
|
"github.com/langhuihui/monibuca/monica/avformat"
|
||||||
"github.com/langhuihui/monibuca/monica/pool"
|
"github.com/langhuihui/monibuca/monica/pool"
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Receiver struct {
|
type Receiver struct {
|
||||||
@@ -26,6 +28,7 @@ func (p *Receiver) Auth(authSub *OutputStream) {
|
|||||||
|
|
||||||
func (p *Receiver) readAVPacket(avType byte) (av *pool.AVPacket, err error) {
|
func (p *Receiver) readAVPacket(avType byte) (av *pool.AVPacket, err error) {
|
||||||
buf := pool.GetSlice(4)
|
buf := pool.GetSlice(4)
|
||||||
|
defer pool.RecycleSlice(buf)
|
||||||
_, err = io.ReadFull(p, buf)
|
_, err = io.ReadFull(p, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
println(err.Error())
|
println(err.Error())
|
||||||
@@ -39,10 +42,7 @@ func (p *Receiver) readAVPacket(avType byte) (av *pool.AVPacket, err error) {
|
|||||||
}
|
}
|
||||||
av.Payload = pool.GetSlice(int(binary.BigEndian.Uint32(buf)))
|
av.Payload = pool.GetSlice(int(binary.BigEndian.Uint32(buf)))
|
||||||
_, err = io.ReadFull(p, av.Payload)
|
_, err = io.ReadFull(p, av.Payload)
|
||||||
if MayBeError(err) {
|
MayBeError(err)
|
||||||
return
|
|
||||||
}
|
|
||||||
pool.RecycleSlice(buf)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,7 +57,7 @@ func PullUpStream(streamPath string) {
|
|||||||
}
|
}
|
||||||
brw := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
|
brw := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
|
||||||
p := &Receiver{
|
p := &Receiver{
|
||||||
Reader: conn,
|
Reader: brw.Reader,
|
||||||
Writer: brw.Writer,
|
Writer: brw.Writer,
|
||||||
}
|
}
|
||||||
if p.Publish(streamPath, p) {
|
if p.Publish(streamPath, p) {
|
||||||
@@ -72,11 +72,7 @@ func PullUpStream(streamPath string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer p.Cancel()
|
defer p.Cancel()
|
||||||
for {
|
for cmd, err := brw.ReadByte(); !MayBeError(err); cmd, err = brw.ReadByte() {
|
||||||
cmd, err := brw.ReadByte()
|
|
||||||
if MayBeError(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case MSG_AUDIO:
|
case MSG_AUDIO:
|
||||||
if audio, err := p.readAVPacket(avformat.FLV_TAG_TYPE_AUDIO); err == nil {
|
if audio, err := p.readAVPacket(avformat.FLV_TAG_TYPE_AUDIO); err == nil {
|
||||||
@@ -103,6 +99,8 @@ func PullUpStream(streamPath string) {
|
|||||||
v.Cancel()
|
v.Cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
log.Printf("unknown cmd:%v", cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,12 +2,13 @@ package jessica
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gobwas/ws"
|
"github.com/gobwas/ws"
|
||||||
. "github.com/langhuihui/monibuca/monica"
|
. "github.com/langhuihui/monibuca/monica"
|
||||||
"github.com/langhuihui/monibuca/monica/avformat"
|
"github.com/langhuihui/monibuca/monica/avformat"
|
||||||
"github.com/langhuihui/monibuca/monica/pool"
|
"github.com/langhuihui/monibuca/monica/pool"
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func WsHandler(w http.ResponseWriter, r *http.Request) {
|
func WsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
12
slave.toml
12
slave.toml
@@ -1,11 +1,11 @@
|
|||||||
# [Plugins.HDL]
|
# [Plugins.HDL]
|
||||||
# ListenAddr = ":2020"
|
# ListenAddr = ":2020"
|
||||||
# [Plugins.Jessica]
|
[Plugins.Jessica]
|
||||||
# ListenAddr = ":8080"
|
ListenAddr = ":8082"
|
||||||
# [Plugins.RTMP]
|
[Plugins.RTMP]
|
||||||
# ListenAddr = ":1935"
|
ListenAddr = ":1936"
|
||||||
# [Plugins.GateWay]
|
[Plugins.GateWay]
|
||||||
# ListenAddr = ":8081"
|
ListenAddr = ":8083"
|
||||||
[Plugins.Cluster]
|
[Plugins.Cluster]
|
||||||
Master = "localhost:2019"
|
Master = "localhost:2019"
|
||||||
#ListenAddr = ":2019"
|
#ListenAddr = ":2019"
|
||||||
|
Reference in New Issue
Block a user