Skyline(6.x)-Web二次開發-多窗口對比
GitHub上獲取源碼
1.打開個3D窗口
一個頁面加載多個TerraExplorer3DWindow和SGWorld等只有第一個能用(即使用iframe也是一樣)
所以我決定打開兩個新頁面實現多窗口對比,然後我在《主頁面》使用window.open打開了兩個《新頁面》,但這兩個新頁面使用SGWorld時居然在主頁面(使用window.open的頁面)產生了效果,感覺和以前的一個頁面加載多個TerraExplorer3DWindow 和 SGWorld效果一樣了!!!
然後經過測試發現關閉主頁面新頁面就正常加載三維地圖了。可以看出使用window.open時主頁面和新頁面是有關聯的,我一開始試了很多方法都斷不開這個關聯,最後決定打開新頁面時多打開一個主頁面,然後關掉主頁面這種笨方法。
當使用window.close當前關閉窗口,居然沒有關上,我一搜發現了關閉前有這一行代碼window.opener=null
opener 屬性是一個可讀可寫的屬性,可返回對創建該窗口的 Window 對象的引用。
opener 屬性非常有用,創建的窗口可以引用創建它的窗口所定義的屬性和函數。
斷開主頁面和新頁面關聯的方法找到了!!!
總結:
使用window.open打開兩個窗口,然後設置window.opener為null,這樣就可以在不同窗口中打開三維場景了。
修正:
今天又測試一下設置window.opener為null不好使,還是使用將主頁面關閉這種方法吧=_=
2.多個3D窗口同步
經測試使用HTTP協議通過web服務器進行多窗口聯動(在頁面攝像機參數改變時修改服務器的瀏覽器位置數據,所有頁面每隔一定時間獲取攝像機參數,當獲取到的攝像機參數與當前三維場景攝像機參數的改變量大於閾值就更新當前三維場景攝像機參數),在每500ms同步一次的條件下不到一分鐘IE瀏覽器就接收或發送HTTP請求就出現問題。然後經過調查資料使用長連接(WebSocket)技術可以處理這種高頻訪問並且多客戶端通信的請求。使用WebSocket完成此功能只需三步即可:
- 客戶端攝像機參數的改變發送給服務器,
- 服務器接收到請求後發送當前坐標給其他客戶端,
- 客戶端接收到消息後更新攝像機參數。
Node.js後端代碼
var express = require(‘express‘);
var http = require(‘http‘);
var WebSocket = require(‘ws‘);
var fs = require(‘fs‘);
var app = express();
var server = http.createServer(app);
var wss = new WebSocket.Server({server});
wss.on(‘connection‘, function connection(ws) {// 創建連接
console.log(‘鏈接成功!‘);
ws.on(‘message‘, function incoming(data) {// 接收消息
wss.clients.forEach(function each(client) {
/*
給全部客戶端(創建連接的客戶端)中
除了發送者客戶端(本次發送給服務器消息的客戶端)的其他客戶端發送消息
*/
if (client != ws) {client.send(data)}
});
});
});
// 啟動WebSocket
server.listen(18848, function listening() {
console.log(‘服務器啟動成功!‘);
});
前端主要js代碼:
import update_pos from ‘./update_pos‘
export default function(){
// ws
this.wsServer = new WebSocket(this.ws_url);
this.wsServer.onopen = function (e) {
(typeof e == ‘string‘) && this.send(e);//向後臺發送數據
};
this.wsServer.onclose = function (e) {//當鏈接關閉的時候觸發
};
this.wsServer.onmessage = function (e) {//後臺返回消息的時候觸發
// console.log(‘get_sync_info‘)
// console.log(data)
var sync_info = JSON.parse(e.data).sync_info
var pos_arr = sync_info.pos
var pos = SGWorld.Creator.CreatePosition(pos_arr[0], pos_arr[1], pos_arr[2], pos_arr[3], pos_arr[4], pos_arr[5]);
SGWorld.Navigate.SetPosition(pos);
};
this.wsServer.onerror = function (e) {//錯誤情況觸發
}
// 定時更新位置
this.last_pos = {};
this.sync_interval = setInterval(update_pos.bind(this), this.interval)
}
Skyline(6.x)-Web二次開發-多窗口對比