修改内存共享逻辑

This commit is contained in:
snltty
2023-11-26 16:25:37 +08:00
parent c46e5a8114
commit 5b1d063dc6
11 changed files with 142 additions and 111 deletions

View File

@@ -96,8 +96,8 @@
1. **【--server】** 服务器ip **192.168.1.18**
2. **【--service】** 服务端口 **1802**
3. **【--share-key】** 自定数据共享 **cmonitor/share**
4. **【--share-len】** 数量 **10**默认10项位置0保留1键盘、2壁纸、3锁屏4 SendSAS0项保留自用不可动
4. **【--share-item-len】** 每项数据长度 **1024**klen+key+vlen+value
4. **【--share-len】** 数量 **10**默认10项位置0保留1键盘、2壁纸、3锁屏4 SendSAS
4. **【--share-item-len】** 每项数据长度 **1024**state(1)+klen(4)+key(klen)+vlen(4)+value(vallen)
###### 服务端
1. **【--web】** 管理UI端口 **1800**

View File

@@ -1,10 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO.MemoryMappedFiles;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@@ -17,6 +13,8 @@ namespace cmonitor.libs
/// </summary>
public sealed class ShareMemory
{
private const int shareMemoryStateSize = 1;
private string key;
private int length;
private int itemSize;
@@ -133,26 +131,26 @@ namespace cmonitor.libs
{
if (accessorGlobal != null && accessorLocal != null)
{
//检查更新状态
if (ReadState(accessorGlobal, 0, ShareMemoryState.Updated) == false)
{
return;
}
WriteState(accessorGlobal, 0, ShareMemoryState.Updated, false);
lock (lockObj)
{
accessorGlobal.ReadArray(0, gloablBytes, 0, gloablBytes.Length);
accessorLocal.WriteArray(0, gloablBytes, 0, itemSize);
for (int i = 1; i < length; i++)
for (int index = 0; index < length; index++)
{
int index = i * itemSize;
int keyLen = BitConverter.ToInt32(gloablBytes, index);
//检查更新状态
if (ReadState(accessorGlobal, index, ShareMemoryState.Updated) == false)
{
continue;
}
int _index = index * itemSize;
int keyLen = BitConverter.ToInt32(gloablBytes, _index + shareMemoryStateSize);
if (keyLen > 0)
{
accessorLocal.WriteArray(index, gloablBytes, index, itemSize);
accessorLocal.WriteArray(_index, gloablBytes, _index, itemSize);
}
WriteState(accessorGlobal, index, ShareMemoryState.Updated, false);
}
WriteState(accessorLocal, 0, ShareMemoryState.Updated, true);
}
}
@@ -164,37 +162,40 @@ namespace cmonitor.libs
if (accessorLocal == null) return dic;
try
{
updated = ReadState(accessorLocal, 0, ShareMemoryState.Updated);
if (updated == false)
{
return dic;
}
lock (lockObj)
{
WriteState(accessorLocal, 0, ShareMemoryState.Updated, false);
accessorLocal.ReadArray(0, bytes, 0, bytes.Length);
for (int i = 1; i < length; i++)
for (int index = 0; index < length; index++)
{
int index = i * itemSize;
int keyLen = BitConverter.ToInt32(bytes, index);
index += 4;
if (keyLen > 0)
{
string key = Encoding.UTF8.GetString(bytes, index, keyLen);
index += keyLen;
//state
bool _updated = ReadState(accessorLocal, index, ShareMemoryState.Updated);
if (_updated == false) continue;
WriteState(accessorLocal, index, ShareMemoryState.Updated, false);
updated |= _updated;
//key length
int _index = index * itemSize + shareMemoryStateSize;
int keyLen = BitConverter.ToInt32(bytes, _index);
_index += 4;
if (keyLen > 0 && keyLen + 8 + shareMemoryStateSize < itemSize)
{
//key
string key = Encoding.UTF8.GetString(bytes, _index, keyLen);
_index += keyLen;
//val length
string val = string.Empty;
int valLen = BitConverter.ToInt32(bytes, index);
index += 4;
if (keyLen + 8 + valLen <= itemSize)
int valLen = BitConverter.ToInt32(bytes, _index);
_index += 4;
//value
if (keyLen + 8 + shareMemoryStateSize + valLen <= itemSize)
{
val = Encoding.UTF8.GetString(bytes, index, valLen);
val = Encoding.UTF8.GetString(bytes, _index, valLen);
}
dic[key] = new ShareItemInfo
{
Index = i,
Index = index,
Value = val
};
}
@@ -212,7 +213,7 @@ namespace cmonitor.libs
MemoryMappedViewAccessor accessor = accessorLocal ?? accessorGlobal;
if (accessor == null) return string.Empty;
index *= itemSize;
index = index * itemSize + shareMemoryStateSize;
accessor.Read(index, out int keylen);
index += 4 + keylen;
@@ -220,7 +221,7 @@ namespace cmonitor.libs
accessor.Read(index, out int vallen);
index += 4;
if (vallen == 0 || keylen + 8 + vallen > itemSize) return string.Empty;
if (vallen == 0 || keylen + 8 + shareMemoryStateSize + vallen > itemSize) return string.Empty;
byte[] bytes = new byte[vallen];
accessor.ReadArray(index, bytes, 0, bytes.Length);
@@ -228,28 +229,28 @@ namespace cmonitor.libs
return Encoding.UTF8.GetString(bytes);
}
public void Update(int index, string key, string value)
public bool Update(int index, string key, string value)
{
if (string.IsNullOrWhiteSpace(key))
{
Update(index,Array.Empty<byte>(), Encoding.UTF8.GetBytes(value));
return Update(index, Array.Empty<byte>(), Encoding.UTF8.GetBytes(value));
}
else
{
Update(index, Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(value));
return Update(index, Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(value));
}
}
public void Update(int index, byte[] key, byte[] value)
public bool Update(int index, byte[] key, byte[] value)
{
try
{
if (accessorLocal == null && accessorGlobal == null) return;
if (index == 0) return;
if (key.Length + 8 + value.Length > itemSize) return;
if (accessorLocal == null && accessorGlobal == null) return false;
if (index == 0) return false;
if (key.Length + 8 + shareMemoryStateSize + value.Length > itemSize) return false;
lock (lockObj)
{
int valIndex = index * itemSize;
int valIndex = index * itemSize + shareMemoryStateSize;
int startIndex = valIndex;
int keylen = key.Length;
int vallen = value.Length;
@@ -293,17 +294,19 @@ namespace cmonitor.libs
}
}
WriteUpdated(index, true);
return true;
}
catch (Exception)
{
}
return false;
}
private bool ReadState(MemoryMappedViewAccessor accessor, int index, ShareMemoryState state)
{
if (accessor == null) return false;
ShareMemoryState stateByte = (ShareMemoryState)accessor.ReadByte(index);
ShareMemoryState stateByte = (ShareMemoryState)accessor.ReadByte(index * itemSize);
return (stateByte & state) == state;
}
public bool ReadUpdated(int index)
@@ -334,7 +337,7 @@ namespace cmonitor.libs
private void WriteState(MemoryMappedViewAccessor accessor, int index, ShareMemoryState state, bool value)
{
if (accessor == null) return;
byte stateValue = accessor.ReadByte(index);
byte stateValue = accessor.ReadByte(index * itemSize);
byte stateByte = (byte)state;
if (value)
{
@@ -344,14 +347,12 @@ namespace cmonitor.libs
{
stateValue &= (byte)(~stateByte);
}
accessor.Write(index, stateValue);
accessor.Write(index * itemSize, stateValue);
}
public void WriteUpdated(int index, bool updated = true)
{
WriteState(accessorLocal, index, ShareMemoryState.Updated, updated);
WriteState(accessorGlobal, index, ShareMemoryState.Updated, updated);
WriteState(accessorLocal, 0, ShareMemoryState.Updated, updated);
WriteState(accessorGlobal, 0, ShareMemoryState.Updated, updated);
}
public void WriteClosed(int index, bool closed = true)
{
@@ -375,11 +376,21 @@ namespace cmonitor.libs
}
}
public struct ShareMemoryStruct
{
public ShareMemoryState State;
public int KeyLength;
public byte[] Key;
public int ValueLength;
public byte[] Value;
};
public enum ShareMemoryState : byte
{
Updated = 0b0000_0001,
Closed = 0b0000_0010,
Running = 0b0000_0100,
All = 0b1111_1111
}
public sealed partial class ShareItemInfo

View File

@@ -19,7 +19,7 @@ namespace cmonitor.sas.service
string shareMkey = "cmonitor/share";
int shareMLength = 10;
int shareItemMLength = 255;
int shareItemMLength = 1024;
int shareIndex = 4;
string mainArgs = string.Empty;
string mainExeName = "cmonitor";
@@ -105,7 +105,7 @@ namespace cmonitor.sas.service
private void WriteAllCloseState(bool state)
{
for (int i = 0; i <= 255; i++)
for (int i = 0; i < shareMLength; i++)
{
shareMemory.WriteClosed(i, state);
}

View File

@@ -61,8 +61,8 @@ export default {
}).catch(() => { });
}
const handleConnect = () => {
//initWebsocket(`ws://192.168.1.18:1801`);
initWebsocket(`ws://${state.api}`);
initWebsocket(`ws://192.168.1.18:1801`);
//initWebsocket(`ws://${state.api}`);
localStorage.setItem('api', state.api);
}
const handleUsername = () => {

View File

@@ -236,6 +236,7 @@ export default {
if (this.globalData.value.reportNames.indexOf(name) == -1) return;
let item = this.globalData.value.devices.filter(c => c.MachineName == name)[0];
if (item) {
item.lastUpdated = Date.now();
item.Screen.fps.temp++;
if (typeof res.Img == 'string') {
this.imgOnload(`data:image/jpg;base64,${res.Img}`).then((img) => {
@@ -253,6 +254,7 @@ export default {
if (this.globalData.value.reportNames.indexOf(name) == -1) return;
let item = this.globalData.value.devices.filter(c => c.MachineName == name)[0];
if (item) {
item.lastUpdated = Date.now();
item.Screen.fps.temp++;
res.Img.arrayBuffer().then((arrayBuffer) => {
const dataView = new DataView(arrayBuffer);
@@ -285,6 +287,7 @@ export default {
if (this.globalData.value.reportNames.indexOf(name) == -1) return;
let item = this.globalData.value.devices.filter(c => c.MachineName == name)[0];
if (item) {
item.lastUpdated = Date.now();
item.Screen.rectangles = res.Rectangles || [];
}
},
@@ -294,11 +297,8 @@ export default {
subNotifyMsg('/notify/report/screen/rectangles', (res, param) => this.handleScreenRectangles(res, param));
},
draw() {
const devices = this.globalData.value.devices.filter(c => this.globalData.value.reportNames.indexOf(c.MachineName) >= 0);
for (let i = 0; i < devices.length; i++) {
const item = devices[i];
getCtx(item) {
if (!item.canvas) {
item.canvas = document.getElementById(`canvas-${item.MachineName}`);
if (item.canvas) {
@@ -307,31 +307,25 @@ export default {
} catch (e) {
item.canvas = null;
}
}
}
if (!item.canvas) continue;
if (!item.infoCanvas) {
item.infoCanvas = document.createElement('canvas');
item.infoCanvas.width = item.canvas.width;
item.infoCanvas.height = item.canvas.height;
item.infoCtx = item.infoCanvas.getContext('2d');
}
if (item.ctx) {
item.infoCtx.clearRect(0, 0, item.infoCanvas.width, item.infoCanvas.height);
const img = item.Screen.fullImg;
if (img) {
//item.Screen.img = null;
item.ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, item.canvas.width, item.canvas.height);
}
}
},
drawRegionImgs(item) {
const regions = item.Screen.regionImgs;
for (let i = 0; i < regions.length; i++) {
const { x, y, w, h } = regions[i].param;
item.infoCtx.drawImage(regions[i], 0, 0, regions[i].width, regions[i].height, x, y, w, h);
}
},
drawInfo(item) {
this.drawRegionImgs(item);
for (let j in item) {
try {
if (item[j] && item[j].draw) {
@@ -341,9 +335,30 @@ export default {
console.log(e);
}
}
},
draw() {
const devices = this.globalData.value.devices.filter(c => this.globalData.value.reportNames.indexOf(c.MachineName) >= 0);
item.ctx.drawImage(item.infoCanvas, 0, 0, item.infoCanvas.width, item.infoCanvas.height, 0, 0, item.canvas.width, item.canvas.height);
for (let i = 0; i < devices.length; i++) {
const item = devices[i];
this.getCtx(item);
if (!item.canvas) {
continue;
}
if (item.lastUpdated == item.lastUpdatedOld) {
continue;
}
item.lastUpdatedOld = item.lastUpdated;
const img = item.Screen.fullImg;
if (img) {
item.ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, item.canvas.width, item.canvas.height);
}
item.infoCtx.clearRect(0, 0, item.infoCanvas.width, item.infoCanvas.height);
this.drawInfo(item);
item.ctx.drawImage(item.infoCanvas, 0, 0, item.infoCanvas.width, item.infoCanvas.height, 0, 0, item.canvas.width, item.canvas.height);
}
requestAnimationFrame(() => {
this.draw();
@@ -353,6 +368,7 @@ export default {
fpsInterval() {
this.globalData.value.devices.forEach(item => {
item.Screen.fps.value = item.Screen.fps.temp;
item.lastUpdated = Date.now();
item.Screen.fps.temp = 0;
});
setTimeout(() => {
@@ -423,6 +439,7 @@ export default {
update(item, report) {
if (!report.Screen) return;
item.lastUpdated = Date.now();
item.Screen.lastInput = report.Screen.LT || 0;
item.Screen.captureTime = report.Screen.CT || 0;
item.Screen.width = report.Screen.W || 0;

View File

@@ -51,7 +51,6 @@ export default {
update(item, report) {
if (!report.Share) return;
console.log(report.Share);
if (report.Share.UserName) {
item.Share.UserName.Index = report.Share.UserName.Index;
item.Share.UserName.Value = report.Share.UserName.Value;

View File

@@ -85,6 +85,7 @@ export default {
item.System.Memory = report.System.Memory;
item.System.Disk = report.System.Disk;
if (report.System.Drives) {
item.lastUpdated = Date.now();
item.System.Drives = report.System.Drives || [];
}

View File

@@ -219,7 +219,7 @@ namespace cmonitor
config.ServicePort = int.Parse(dic["service"]);
config.ShareMemoryKey = dic["share-key"];
config.ShareMemoryLength = int.Parse(dic["share-len"]);
config.ShareMemoryItemLength = int.Parse(dic["share-item-len"]);
config.ShareMemoryItemSize = int.Parse(dic["share-item-len"]);
config.ReportDelay = int.Parse(dic["report-delay"]);
config.ScreenScale = float.Parse(dic["screen-scale"]);
config.ScreenDelay = int.Parse(dic["screen-delay"]);
@@ -297,12 +297,20 @@ namespace cmonitor
public float ScreenScale { get; set; } = 0.2f;
public int ScreenDelay { get; set; } = 30;
/// <summary>
/// 0项保留给各个功能的状态信息每个一个字节为状态信息看ShareMemoryState
/// </summary>
public string ShareMemoryKey { get; set; } = "cmonitor/share";
public int ShareMemoryLength { get; set; } = 10;
public int ShareMemoryItemSize { get; set; } = 1024;
[JsonIgnore]
public bool SaveSetting { get; set; } = true;
[JsonIgnore]
public bool WakeUp { get; set; } = true;
[JsonIgnore]
public bool VolumeMasterPeak { get; set; } = true;
public bool VolumeMasterPeak { get; set; } = false;
[JsonIgnore]
@@ -311,16 +319,9 @@ namespace cmonitor
public bool IsCLient { get; set; }
[JsonIgnore]
public bool IsServer { get; set; }
[JsonIgnore]
public bool Elevated { get; set; }
/// <summary>
/// 0项保留给各个功能的状态信息每个一个字节为状态信息看ShareMemoryState
/// </summary>
public string ShareMemoryKey { get; set; } = "cmonitor/share";
public int ShareMemoryLength { get; set; } = 10;
public int ShareMemoryItemLength { get; set; } = 1024;
//键盘
public const int ShareMemoryKeyBoardIndex = 1;
@@ -371,6 +372,7 @@ namespace cmonitor
&& ValidateReport(dic, out error)
&& ValidateElevated(dic, out error);
}
static bool ValidateMode(Dictionary<string, string> dic)
{
//模式
@@ -380,6 +382,7 @@ namespace cmonitor
}
return true;
}
static bool ValidateServer(Dictionary<string, string> dic, out string error)
{
error = string.Empty;
@@ -390,6 +393,7 @@ namespace cmonitor
}
return true;
}
static bool ValidateName(Dictionary<string, string> dic, out string error)
{
error = string.Empty;
@@ -457,6 +461,7 @@ namespace cmonitor
}
return true;
}
static bool ValidateReport(Dictionary<string, string> dic, out string error)
{
error = string.Empty;
@@ -477,7 +482,5 @@ namespace cmonitor
return true;
}
}
}

View File

@@ -53,7 +53,7 @@ namespace cmonitor.server.client.reports.llock
if (open)
{
CommandHelper.Windows(string.Empty, new string[] {
$"start llock.win.exe {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemLength} {Config.ShareMemoryLLockIndex}"
$"start llock.win.exe {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemSize} {Config.ShareMemoryLLockIndex}"
});
}
});

View File

@@ -34,7 +34,7 @@ namespace cmonitor.server.client.reports.share
{
if (OperatingSystem.IsWindows())
{
shareMemory = new ShareMemory(config.ShareMemoryKey, config.ShareMemoryLength, config.ShareMemoryItemLength);
shareMemory = new ShareMemory(config.ShareMemoryKey, config.ShareMemoryLength, config.ShareMemoryItemSize);
shareMemory.InitLocal();
shareMemory.InitGlobal();
shareMemory.WriteRunning(0, true);

View File

@@ -49,7 +49,7 @@ namespace cmonitor.server.client.reports.llock
if (open)
{
CommandHelper.Windows(string.Empty, new string[] {
$"start wallpaper.win.exe \"{url}\" {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemLength} {Config.ShareMemoryKeyBoardIndex} {Config.ShareMemoryWallpaperIndex}"
$"start wallpaper.win.exe \"{url}\" {config.ShareMemoryKey} {config.ShareMemoryLength} {config.ShareMemoryItemSize} {Config.ShareMemoryKeyBoardIndex} {Config.ShareMemoryWallpaperIndex}"
});
}
});