# 长春轻轨web项目技术栈
# 一、运用框架、API
- Vue
- Vuex
- 百度地图接口
- element
# 二、项目结构
- 布局
- 左侧百度地图接口
- 右侧垂直导航栏
- 功能
- 实时数据
- 视频数据
- 地图坐标查询
├─components
│ Aircondition.vue
│ BaiduMap.vue
│ Car.vue
│ CurrentFault.vue
│ DashBoard.vue //速度仪表盘
│ Device.vue
│ Door.vue
│ Electric.vue
│ FaultPage.vue
│ History.vue
│ HistoryFault.vue
│ Interface.vue //弹出窗口主界面
│ main.vue //入口文件
│ Modal.vue
│ Net.vue
│ ProgressBar.vue //自定义双端进度条
│ Video.vue
│ WindowFrame.vue //弹出窗口
│
├─css
│ demo.css
│
├─entity
│ singleCar.js
│ singleFault.js
│
├─router
│ index.js
│
├─service
│ AnalysisMsg.js //实时数据websocket连接所用函数
│ WebSocket.js //实时数据websocket连接
│ wfs.js //wfs连接视频端口,解码246流
│
└─store
│ store.js //vuex管理状态
│
└─modules
airStore.js
carStore.js
deviceStore.js
doorStore.js
electricStore.js
faultStore.js
headInfoStore.js
interfaceStore.js
netStore.js
stateInfoStore.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 三、整体功能
# (1)、点击线路,出现线路所属车辆
# 1.车辆列表(总表和显示表):
var car_list = new Array(); //车辆列表
var show_list = new Array()
car_list[0] = new singleCar(1,8888)
car_list[1] = new singleCar(1,7777)
car_list[2] = new singleCar(2,6666)
car_list[3] = new singleCar(3,5555)
car_list[4] = new singleCar(3,4444)
car_list[5] = new singleCar(4,3333)
# 2.车辆实体:
//singleCar.js
function singleCar(carLine, carNumber, mode) {
this.carLine = carLine
this.carNumber = carNumber
this.mode = "离线"
}
export {
singleCar,
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 3.点击线路,将该线路车辆加入到显示列表:
getCars(i){
this.carLineIndex = i;
show_list.length = 0
this.setState()
console.log("--------------------------------------------------------------------选择线路:"+this.carLineIndex)
for(var j=0;j<car_list.length;j++){
if(car_list[j].carLine == i){
show_list.push(car_list[j])
}
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 4.点击具体车辆,检查车辆 mode,为运行时发送请求实时数据,并将车号 carNumber 传到新建小窗口页面:
<el-submenu index="1">
<template slot="title"><i class="el-icon-truck"></i>机车查询结果列表</template>
<el-menu-item
v-for="(item) in show_list"
v-bind:key="item.carNumber"
@click=" (item.mode == '运行') ? false:true && sendMessage(JSON.stringify({type:3,carNum:item.carNumber}))"
@click.native="showOne(item.mode,item.carNumber)"
>{{item.carNumber}} {{item.mode}}</el-menu-item>
</el-submenu>
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# (2)、Vuex 状态管理
import Vue from 'vue'
const state = {
test:[]
//这里填写参数信息
}
const getters = {
test: (state) => {
return state.test
}
}
const actions = {
}
const mutations = {
//这里写你的函数
createInfo(state) {
Vue.set(state.test, 0, "测试")
//由于 Vue 不能检测到对象属性的添加或删除,所以不能用 test[0]="测试"这种方式为参数添加新属性或新值。
}
}
export default {
state,
getters,
actions,
mutations,
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# (3)、H.264 裸流视频播放
用到了 github 上的 ChihChengYang 的 wfs.js 和 index.html
# 1.在 Vue 中可以这样写视频页:
<template>
<div id="Video">
<div id="videoBorder">
<video id="video1" width="640" height="480" autoplay></video>
</div>
</div>
</template>
<script>
import wfs from '../service/wfs.js'
import {split,initWebpack,websocketSend, websocket} from '../service/WebSocket'
window.onload = function() {
if (Wfs.isSupported()) {
var video1 = document.getElementById("video1"),
wfs = new Wfs();
wfs.attachMedia(video1, 'ch1');
}
};
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 2.然后在你添加到项目中的 wfs.js 文件中更改你的 websocket 连接路径,搜索 onMediaAttached 找到创建 websocket 的函数,按以下方式修改:
key: 'onMediaAttached',
value: function onMediaAttached(data) {
if (data.websocketName != undefined) {
var url = "你的连接地址"
var client = new WebSocket(url)
//clientSocket = client
//(如果你要调用wfs.js中的websocket发送函数,你需要用到这行代码)
this.wfs.attachWebsocket(client, data.channelName);
} else {
console.log('websocketName ERROE!!!');
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
- 去掉缓存:注释 onSBUpdateEnd 方法里的 this.mediaSource.endOfStream() 和 that.media.play()这两行,然后在 video 标签里加上 autoplay,去掉 controls。
- 调整播放速度:将 this.H264_TIMEBASE = 3000 中的数值改为 4500(或其他你觉得合适的数值),有两个地方需要修改。
# 3.现在你就可以在浏览器上运行你的项目,看看是否有画面出现。在项目试验过程中可能出现以下问题:
- 花屏:可能是服务端出了问题,可以在服务端写文件进行测试。
- 可能会出现 mediaError 的打印日志,但并不影响画面播放。
# 4.如果你想在外部调用 websocket 发送你的项目所要求的请求视频数据,请接着看。
(参考网址: JS如何在外部调用函数内部的函数 )
- 下面是接受 H.264 裸流并进行转化的函数:
key: 'receiveSocketMessage',
value: function receiveSocketMessage(event) {
this.buf = new Uint8Array(event.data);
var copy = new Uint8Array(this.buf);
if (this.mediaType === 'FMp4') {
this.wfs.trigger(_events2.default.WEBSOCKET_ATTACHED, { payload: copy });
}
if (this.mediaType === 'H264Raw') {
this.wfs.trigger(_events2.default.H264_DATA_PARSING, { data: copy });
}
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- 在整个 wfs.js 文件函数的最外层定义变量:
var sendMsg;
var clientSocket;
1
2
2
- 在 send 函数中赋值:
key: 'onWebsocketMessageSending',
value: function onWebsocketMessageSending(i) {
clientSocket.send(i)
console.log('发送数据:' + i)
//this.client.send(i)
//this.client.send(JSON.stringify({ type: 2, carNum: 8888 }))
sendMsg = onWebsocketMessageSending
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- 在函数最后 export 出去:
export {
sendMsg,
clientSocket,
}
1
2
3
4
2
3
4
- 在你想调用的页面 import:
import {sendMsg,clientSocket} from '../service/wfs.js'
1
使用过程中的提问和解答:https://github.com/ChihChengYang/wfs.js/issues/31
# (4)、axios 进行 http 请求
1.在 main.js 中添加以下代码:
//main.js
import axios from 'axios'
Vue.prototype.$http = axios;
1
2
3
2
3
2.新建 http.js 文件:
//http.js
import axios from 'axios'
export default {
install(Vue) {
//install方法,向Vue实例中添加一个$http方法
Vue.prototype.$http = axios
Vue.$http = axios
},
$http: axios
}
export const Http = axios
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
3.在要进行 http 请求的页面写请求方法:
//http请求方法
requestData:function(){
console.log('http请求,'+'time:'+this.duration);
console.log('url:'+url+this.className)
this.$http.get(
url,
{
params:{
date1:this.duration[0],
date2:this.duration[1],
}
}
)
.then(res => {
var ans = res.data;
console.log('res.data:'+res.data);
console.log('value0:'+this.duration);
if(res.data.code == '0'){
console.log('yes');
}else{
alert('数据不存在');
}
})
.catch(err => {
alert('请求失败!');
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
P.s. 根据项目需求,具体的请求方法参数会不一样。
# 四、其他
# 1.学到的一些基础知识点:
- CSS 中的 position 定位:relative&absolute
# 2.不足与可改进之处:
- 主界面的车辆车门,用 flex 布局或网格布局会更好
- 网络界面,选定布局,由大到小来画会更有规律,更好修改