ntminer 3 years ago
parent
commit
c7b478f3cb
59 changed files with 459 additions and 335 deletions
  1. 2 2
      README.md
  2. 3 3
      docs/WebSite/index.html
  3. 13 6
      src/AppModels/Vms/KernelProfileViewModel.cs
  4. 19 4
      src/AppViews0/Views/Ucs/CoinPage.xaml
  5. 0 1
      src/AppViews0/Views/Ucs/MinerProfileIndex.xaml.cs
  6. 13 3
      src/AppViews0/Views/Ucs/PoolSelect.xaml
  7. BIN
      src/MinerClient/Daemon/NTMinerDaemon.exe.lnk
  8. 0 7
      src/NTMiner.Controllers/IReportBinaryController.cs
  9. 0 8
      src/NTMiner.Controllers/IReportController.cs
  10. 0 2
      src/NTMiner.Controllers/NTMiner.Controllers.csproj
  11. 20 14
      src/NTMinerClient/Core/Impl/CalcConfigSet.cs
  12. 0 6
      src/NTMinerClient/Messages.cs
  13. 1 1
      src/NTMinerDataSchemas/NTKeyword.cs
  14. 3 0
      src/NTMinerDataSchemas/Ws/WsMessage.cs
  15. 3 0
      src/NTMinerNoDevFee/NTMinerNoDevFee.csproj
  16. 4 6
      src/NTMinerRpcClient/Core/Impl/KernelOutputKeywordSet.cs
  17. 0 2
      src/NTMinerRpcClient/NTMinerRpcClient.csproj
  18. 4 1
      src/NTMinerRpcClient/Rpc/Impl/BinaryRequestJsonResponseRpcHelper.cs
  19. 8 2
      src/NTMinerRpcClient/Rpc/Impl/JsonRequestBinaryResponseRpcHelper.cs
  20. 4 1
      src/NTMinerRpcClient/Rpc/Impl/JsonRpcHelper.cs
  21. 4 1
      src/NTMinerRpcClient/Rpc/Impl/JsonRpcHelper.partials.cs
  22. 0 22
      src/NTMinerRpcClient/Services/Official/ReportBinaryService.cs
  23. 0 35
      src/NTMinerRpcClient/Services/Official/ReportService.cs
  24. 0 2
      src/NTMinerRpcClient/Services/OfficialServices.cs
  25. 13 0
      src/NTMinerServer/Core/IReadOnlyCalcConfigSet.cs
  26. 56 0
      src/NTMinerServer/Core/Impl/ReadOnlyCalcConfigSet.cs
  27. 5 0
      src/NTMinerServer/Core/Messages.cs
  28. 18 0
      src/NTMinerServer/Core/Mq/MqMessagePaths/CalcConfigMqMessagePath.cs
  29. 10 0
      src/NTMinerServer/Core/Redis/ICalcConfigDataRedis.cs
  30. 48 0
      src/NTMinerServer/Core/Redis/Impl/CalcConfigDataRedis.cs
  31. 1 0
      src/NTMinerServer/MqKeyword.cs
  32. 6 0
      src/NTMinerServer/NTMinerServer.csproj
  33. 25 0
      src/NTMinerServer/ReadOnlyCalcConfigSetExtensions.cs
  34. 4 0
      src/NTMinerServer/RedisKeyword.cs
  35. 1 1
      src/NTMinerWpf/Views/LocalIpConfig.xaml
  36. 5 0
      src/NTMinerlib/Messages.cs
  37. 22 0
      src/NTMinerlib/NTMinerHttpException.cs
  38. 1 0
      src/NTMinerlib/NTMinerlib.csproj
  39. 5 2
      src/WebApiServer/AppRoot.cs
  40. 1 15
      src/WebApiServer/Controllers/CalcConfigController.cs
  41. 0 19
      src/WebApiServer/Controllers/ReportBinaryController.cs
  42. 0 56
      src/WebApiServer/Controllers/ReportController.cs
  43. 1 7
      src/WebApiServer/Core/ICalcConfigSet.cs
  44. 11 57
      src/WebApiServer/Core/Impl/CalcConfigSet.cs
  45. 5 0
      src/WebApiServer/Core/Mq/Senders/ICalcConfigMqSender.cs
  46. 26 0
      src/WebApiServer/Core/Mq/Senders/Impl/CalcConfigMqSender.cs
  47. 1 3
      src/WebApiServer/SpecialPath.cs
  48. 7 0
      src/WebApiServer/SpecialPath.partials.cs
  49. 3 2
      src/WebApiServer/WebApiServer.csproj
  50. 21 17
      src/WebApiServer/app.config
  51. 15 8
      src/WsServer/AppRoot.cs
  52. 1 2
      src/WsServer/Core/ISession.cs
  53. 3 3
      src/WsServer/Core/Impl/AbstractSession.cs
  54. 3 6
      src/WsServer/Core/Impl/AbstractSessionSet`1.cs
  55. 1 2
      src/WsServer/Core/Impl/MinerClientSessionSet.cs
  56. 3 6
      src/WsServer/Core/Impl/MinerStudioSessionSet.cs
  57. 17 0
      src/WsServer/WsMessageFromMinerClientHandler.cs
  58. 16 0
      src/WsServer/WsMessageFromMinerStudioHandler.cs
  59. 3 0
      src/WsServer/WsServer.csproj

+ 2 - 2
README.md

@@ -1,6 +1,6 @@
 ## [开源矿工官网](http://dl.ntminer.top/)
 
-点击加入 [NTMiner官方QQ群](https://jq.qq.com/?_wv=1027&k=J2u6TzsN): 958352610
+点击加入 [NTMiner官方QQ群](点击链接加入群聊【¹⁴开源矿工】:https://jq.qq.com/?_wv=1027&k=InoblLNZ): 892646046
 
 1. 开源矿工内置的所有内核均为原版,开源矿工永远不会额外增加矿工支出;
 2. 开源矿工永远开源;
@@ -36,7 +36,7 @@
 
 类似开源矿工这些同类挖矿辅助工具降低了挖矿门槛帮助矿工管理矿机,获得一点收入是合理的,但是不能偷。
 
-点击加入 [NTMiner官方QQ群](https://jq.qq.com/?_wv=1027&k=J2u6TzsN): 958352610
+点击加入 [NTMiner官方QQ群](点击链接加入群聊【¹⁴开源矿工】:https://jq.qq.com/?_wv=1027&k=InoblLNZ): 892646046
 
 # 授权协议
 The LGPL license。

+ 3 - 3
docs/WebSite/index.html

@@ -206,8 +206,8 @@
             </section>
 
             <div class="wechat">
-                <a href="https://jq.qq.com/?_wv=1027&k=rHE4P02o" target="_blank">
-                    <img src="https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/NTMiner_QQGroupQrCode.png#20210928" style="width:280px;" alt="QQ群">
+                <a href="点击链接加入群聊【¹⁴开源矿工】:https://jq.qq.com/?_wv=1027&k=InoblLNZ" target="_blank">
+                    <img src="https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/NTMiner_QQGroupQrCode.png#20211127" style="width:280px;" alt="QQ群">
                 </a>
             </div>
         </div>
@@ -232,7 +232,7 @@
                     </div>
                     <div class="col-sm-4 footer-item col-xl-3  col-md-4">
                         <h6>联系方式</h6>
-                        <img data-toggle="tooltip" data-placement="top" title="" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCIgdmlld0JveD0iMCAwIDMwIDMwIj4KICAgIDxwYXRoIGZpbGw9IiM3NzciIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTQuNzU2IDE2Ljg1NWMtLjg2OSAyLjExMy0xLjAxIDQuMTI4LS4zMTMgNC41MDUuNDgxLjI2IDEuMjM1LS4zMyAxLjk0LTEuNDE1LjI4IDEuMTgxLjk3IDIuMjUgMS45NTggMy4xMDgtMS4wMzUuMzk1LTEuNzEyIDEuMDQtMS43MTIgMS43NzIgMCAxLjIwMiAxLjgzIDIuMTc1IDQuMDkgMi4xNzUgMi4wMzggMCAzLjcyNi0uNzkgNC4wMzctMS44M2guNDg2Yy4zMTMgMS4wNCAyLjAwMyAxLjgzIDQuMDM5IDEuODMgMi4yNiAwIDQuMDktLjk3NCA0LjA5LTIuMTc1IDAtLjczLS42NzYtMS4zNzctMS43MTMtMS43NzIuOTg3LS44NTggMS42OC0xLjkyNyAxLjk1OS0zLjEwOC43MDUgMS4wODQgMS40NTcgMS42NzUgMS45MzggMS40MTUuNjk4LS4zNzcuNTYtMi4zOTMtLjMxMS00LjUwNS0uNjgyLTEuNjYtMS42MDgtMi44ODItMi4zMTYtMy4xNTIuMDEtLjEwNS4wMTUtLjIxMi4wMTUtLjMyIDAtLjY0LS4xNzItMS4yMzMtLjQ2Ny0xLjcxNi4wMDUtLjAzOC4wMDUtLjA3Ni4wMDUtLjExNGExLjg2IDEuODYgMCAwIDAtLjE4NC0uODFDMjIuMTIgNi40MjYgMTkuNCAzIDE1IDNjLTQuNDAyIDAtNy4xMjIgMy40MjctNy4zIDcuNzQyYTEuODUzIDEuODUzIDAgMCAwLS4xODQuODExYzAgLjAzOC4wMDMuMDc2LjAwNC4xMTRhMy4zMTkgMy4zMTkgMCAwIDAtLjQ2NSAxLjcxN2MwIC4xMDcuMDA0LjIxMy4wMTMuMzItLjcwMy4yNjktMS42MzIgMS40OTQtMi4zMTIgMy4xNTF6Ii8+Cjwvc3ZnPgo=" data-html="true" alt="QQ icon" data-original-title="&lt;img src=&#39;https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/NTMiner_QQGroupQrCode.png#20210928&#39; width=&#39;190px&#39;&gt; ">
+                        <img data-toggle="tooltip" data-placement="top" title="" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCIgdmlld0JveD0iMCAwIDMwIDMwIj4KICAgIDxwYXRoIGZpbGw9IiM3NzciIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTQuNzU2IDE2Ljg1NWMtLjg2OSAyLjExMy0xLjAxIDQuMTI4LS4zMTMgNC41MDUuNDgxLjI2IDEuMjM1LS4zMyAxLjk0LTEuNDE1LjI4IDEuMTgxLjk3IDIuMjUgMS45NTggMy4xMDgtMS4wMzUuMzk1LTEuNzEyIDEuMDQtMS43MTIgMS43NzIgMCAxLjIwMiAxLjgzIDIuMTc1IDQuMDkgMi4xNzUgMi4wMzggMCAzLjcyNi0uNzkgNC4wMzctMS44M2guNDg2Yy4zMTMgMS4wNCAyLjAwMyAxLjgzIDQuMDM5IDEuODMgMi4yNiAwIDQuMDktLjk3NCA0LjA5LTIuMTc1IDAtLjczLS42NzYtMS4zNzctMS43MTMtMS43NzIuOTg3LS44NTggMS42OC0xLjkyNyAxLjk1OS0zLjEwOC43MDUgMS4wODQgMS40NTcgMS42NzUgMS45MzggMS40MTUuNjk4LS4zNzcuNTYtMi4zOTMtLjMxMS00LjUwNS0uNjgyLTEuNjYtMS42MDgtMi44ODItMi4zMTYtMy4xNTIuMDEtLjEwNS4wMTUtLjIxMi4wMTUtLjMyIDAtLjY0LS4xNzItMS4yMzMtLjQ2Ny0xLjcxNi4wMDUtLjAzOC4wMDUtLjA3Ni4wMDUtLjExNGExLjg2IDEuODYgMCAwIDAtLjE4NC0uODFDMjIuMTIgNi40MjYgMTkuNCAzIDE1IDNjLTQuNDAyIDAtNy4xMjIgMy40MjctNy4zIDcuNzQyYTEuODUzIDEuODUzIDAgMCAwLS4xODQuODExYzAgLjAzOC4wMDMuMDc2LjAwNC4xMTRhMy4zMTkgMy4zMTkgMCAwIDAtLjQ2NSAxLjcxN2MwIC4xMDcuMDA0LjIxMy4wMTMuMzItLjcwMy4yNjktMS42MzIgMS40OTQtMi4zMTIgMy4xNTF6Ii8+Cjwvc3ZnPgo=" data-html="true" alt="QQ icon" data-original-title="&lt;img src=&#39;https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/NTMiner_QQGroupQrCode.png#20211127&#39; width=&#39;190px&#39;&gt; ">
                         <!--<img style="margin-left:8px" data-toggle="tooltip" data-placement="top" title="" src="https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/footer-icon-wechat.svg?v=01692ab" data-html="true" alt="WeChat icon" data-original-title="&lt;img src=&#39;https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/wechat-pic.jpg&#39; width=&#39;190px&#39;&gt;">-->
                     </div>
                 </div>

+ 13 - 6
src/AppModels/Vms/KernelProfileViewModel.cs

@@ -263,14 +263,21 @@ namespace NTMiner.Vms {
                     });
                 };
                 RpcRoot.OfficialServer.FileUrlService.GetPackageUrlAsync(package, (packageUrl, e) => {
-                    if (string.IsNullOrEmpty(packageUrl)) {
-                        string msg = $"未获取到{package}内核包下载地址";
-                        downloadComplete?.Invoke(false, msg, saveFileFullName);
-                        VirtualRoot.ThisLocalError(nameof(KernelProfileViewModel), msg, toConsole: true);
+                    if (e != null && e is NTMinerHttpException httpE) {
+                        if (httpE.StatusCode >= HttpStatusCode.InternalServerError) {
+                            VirtualRoot.Out.ShowError("服务器忙");
+                        }
                     }
                     else {
-                        VirtualRoot.ThisLocalInfo(nameof(KernelProfileViewModel), "下载:" + package, toConsole: true);
-                        webClient.DownloadFileAsync(new Uri(packageUrl), saveFileFullName);
+                        if (string.IsNullOrEmpty(packageUrl)) {
+                            string msg = $"未获取到{package}内核包下载地址";
+                            downloadComplete?.Invoke(false, msg, saveFileFullName);
+                            VirtualRoot.ThisLocalError(nameof(KernelProfileViewModel), msg, toConsole: true);
+                        }
+                        else {
+                            VirtualRoot.ThisLocalInfo(nameof(KernelProfileViewModel), "下载:" + package, toConsole: true);
+                            webClient.DownloadFileAsync(new Uri(packageUrl), saveFileFullName);
+                        }
                     }
                 });
             }

+ 19 - 4
src/AppViews0/Views/Ucs/CoinPage.xaml

@@ -226,7 +226,6 @@
 								<DataGridTemplateColumn.CellTemplate>
 									<DataTemplate>
 										<StackPanel 
-											IsEnabled="{Binding IsReadOnly, Converter={StaticResource BoolInvertConverter}}"
 											HorizontalAlignment="Right" 
 											Background="Transparent" 
 											VerticalAlignment="Center" 
@@ -245,6 +244,7 @@
 											</controls:KbButton>
 											<controls:KbButton Command="{Binding Remove}" Background="Transparent" BorderThickness="0"
 												Margin="2 0"
+												IsEnabled="{Binding IsReadOnly, Converter={StaticResource BoolInvertConverter}}"
 												CornerRadius="2" ToolTip="删除">
 												<WrapPanel>
 													<Path
@@ -257,6 +257,7 @@
 											</controls:KbButton>
 											<controls:KbButton 
 												Margin="2 0"
+												IsEnabled="{Binding IsReadOnly, Converter={StaticResource BoolInvertConverter}}"
 												Command="{Binding SortDown}" ToolTip="下移" 
 												Background="Transparent" BorderThickness="0"
 												CornerRadius="2">
@@ -271,6 +272,7 @@
 											</controls:KbButton>
 											<controls:KbButton 
 												Margin="2 0"
+												IsEnabled="{Binding IsReadOnly, Converter={StaticResource BoolInvertConverter}}"
 												Command="{Binding SortUp}" ToolTip="上移" 
 												Background="Transparent" BorderThickness="0"
 												CornerRadius="2">
@@ -326,7 +328,10 @@
 							</DataGridTextColumn>
 							<DataGridTemplateColumn Width="*" IsReadOnly="True">
 								<DataGridTemplateColumn.Header>
-									<TextBlock Text="地址"></TextBlock>
+                                    <WrapPanel>
+                                        <TextBlock Text="地址"></TextBlock>
+                                        <TextBlock Margin="4 0 0 0" Foreground="Red" Text="双击行打开编辑页"></TextBlock>
+                                    </WrapPanel>
 								</DataGridTemplateColumn.Header>
 								<DataGridTemplateColumn.CellTemplate>
 									<DataTemplate>
@@ -336,8 +341,18 @@
 										</StackPanel>
 									</DataTemplate>
 								</DataGridTemplateColumn.CellTemplate>
-							</DataGridTemplateColumn>
-							<DataGridTemplateColumn 
+                            </DataGridTemplateColumn>
+                            <DataGridTemplateColumn Width="160" IsReadOnly="True">
+                                <DataGridTemplateColumn.Header>
+                                    <TextBlock Text="重写地址"></TextBlock>
+                                </DataGridTemplateColumn.Header>
+                                <DataGridTemplateColumn.CellTemplate>
+                                    <DataTemplate>
+                                        <TextBlock Text="{Binding PoolProfileVm.Server}"></TextBlock>
+                                    </DataTemplate>
+                                </DataGridTemplateColumn.CellTemplate>
+                            </DataGridTemplateColumn>
+                            <DataGridTemplateColumn 
 								Visibility="{x:Static app:AppStatic.IsDevModeVisible}"
 								IsReadOnly="True">
 								<DataGridTemplateColumn.Header>

+ 0 - 1
src/AppViews0/Views/Ucs/MinerProfileIndex.xaml.cs

@@ -300,7 +300,6 @@ namespace NTMiner.Views.Ucs {
             }
             else {
                 OpenMainCoinWalletPopup();
-                UserActionHappend();
             }
             e.Handled = true;
         }

+ 13 - 3
src/AppViews0/Views/Ucs/PoolSelect.xaml

@@ -140,7 +140,7 @@
 						</DataTemplate>
 					</DataGridTemplateColumn.CellTemplate>
 				</DataGridTemplateColumn>
-				<DataGridTemplateColumn Width="230" IsReadOnly="True">
+				<DataGridTemplateColumn Width="160" IsReadOnly="True">
 					<DataGridTemplateColumn.Header>
 						<TextBlock Text="地址"></TextBlock>
 					</DataGridTemplateColumn.Header>
@@ -149,8 +149,18 @@
 							<TextBlock Text="{Binding Server}"></TextBlock>
 						</DataTemplate>
 					</DataGridTemplateColumn.CellTemplate>
-				</DataGridTemplateColumn>
-				<DataGridTemplateColumn Width="40" IsReadOnly="True">
+                </DataGridTemplateColumn>
+                <DataGridTemplateColumn Width="160" IsReadOnly="True">
+                    <DataGridTemplateColumn.Header>
+                        <TextBlock Text="重写地址"></TextBlock>
+                    </DataGridTemplateColumn.Header>
+                    <DataGridTemplateColumn.CellTemplate>
+                        <DataTemplate>
+                            <TextBlock Text="{Binding PoolProfileVm.Server}"></TextBlock>
+                        </DataTemplate>
+                    </DataGridTemplateColumn.CellTemplate>
+                </DataGridTemplateColumn>
+                <DataGridTemplateColumn Width="40" IsReadOnly="True">
 					<DataGridTemplateColumn.CellTemplate>
 						<DataTemplate>
                             <controls:KbLinkButton

BIN
src/MinerClient/Daemon/NTMinerDaemon.exe.lnk


+ 0 - 7
src/NTMiner.Controllers/IReportBinaryController.cs

@@ -1,7 +0,0 @@
-using NTMiner.Report;
-
-namespace NTMiner.Controllers {
-    public interface IReportBinaryController {
-        //ReportResponse ReportSpeed();
-    }
-}

+ 0 - 8
src/NTMiner.Controllers/IReportController.cs

@@ -1,8 +0,0 @@
-using NTMiner.Report;
-
-namespace NTMiner.Controllers {
-    public interface IReportController {
-        //ReportResponse ReportSpeed(SpeedDto speedDto);
-        //void ReportState(ReportState request);
-    }
-}

+ 0 - 2
src/NTMiner.Controllers/NTMiner.Controllers.csproj

@@ -43,7 +43,6 @@
     <Compile Include="ICaptchaController`1.cs" />
     <Compile Include="IMinerClientController.cs" />
     <Compile Include="INTMinerFileController.cs" />
-    <Compile Include="IReportBinaryController.cs" />
     <Compile Include="IServerMessageBinaryController`1.cs" />
     <Compile Include="IUserAppSettingController.cs" />
     <Compile Include="IWsServerNodeController.cs" />
@@ -59,7 +58,6 @@
     <Compile Include="INTMinerDaemonController.cs" />
     <Compile Include="INTMinerWalletController.cs" />
     <Compile Include="IOverClockDataController.cs" />
-    <Compile Include="IReportController.cs" />
     <Compile Include="IServerMessageController.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>

+ 20 - 14
src/NTMinerClient/Core/Impl/CalcConfigSet.cs

@@ -12,31 +12,37 @@ namespace NTMiner.Core.Impl {
         public CalcConfigSet(INTMinerContext ntminerContext) {
             _ntminerContext = ntminerContext;
             if (ClientAppType.IsMinerClient) {
-                VirtualRoot.BuildOnecePath<HasBoot20SecondEvent>("初始化收益计算器", LogEnum.DevConsole, pathId: PathId.Empty, location: this.GetType(), PathPriority.Normal,
+                VirtualRoot.BuildEventPath<MineStartedEvent>("开始挖矿时加载收益计算器数据", LogEnum.DevConsole, location: this.GetType(), PathPriority.Normal,
                     path: message => {
                         Init();
                     });
             }
         }
 
+        private List<string> _coinCodes = new List<string>();
         private DateTime _initedOn = DateTime.MinValue;
-
         public void Init(bool forceRefresh = false) {
+            List<string> coinCodes = new List<string>();
+            var mineContext = NTMinerContext.Instance.CurrentMineContext;
+            if (!forceRefresh && mineContext != null) {
+                if (mineContext.MainCoin != null) {
+                    coinCodes.Add(mineContext.MainCoin.Code);
+                }
+                if (mineContext is IDualMineContext dualMineContext) {
+                    if (dualMineContext.DualCoin != null) {
+                        coinCodes.Add(dualMineContext.DualCoin.Code);
+                    }
+                }
+            }
             DateTime now = DateTime.Now;
             // 如果未显示主界面则收益计算器也不用更新了
-            if ((_initedOn == DateTime.MinValue || NTMinerContext.IsUiVisible || ClientAppType.IsMinerStudio) && (forceRefresh || _initedOn.AddMinutes(10) < now)) {
+            if ((_initedOn == DateTime.MinValue || NTMinerContext.IsUiVisible || ClientAppType.IsMinerStudio)
+                && (forceRefresh || (_coinCodes.Count != 0 && coinCodes.Any(a => !_coinCodes.Contains(a))) || _initedOn.AddMinutes(10) < now)) {
                 _initedOn = now;
-                List<string> coinCodes = new List<string>();
-                var mineContext = NTMinerContext.Instance.CurrentMineContext;
-                if (!forceRefresh && mineContext != null) {
-                    if (mineContext.MainCoin != null) {
-                        coinCodes.Add(mineContext.MainCoin.Code);
-                    }
-                    if (mineContext is IDualMineContext dualMineContext) {
-                        if (dualMineContext.DualCoin != null) {
-                            coinCodes.Add(dualMineContext.DualCoin.Code);
-                        }
-                    }
+                _coinCodes = coinCodes;
+                if (forceRefresh) {
+                    // 传空表示获取全部
+                    _coinCodes.Clear();
                 }
                 RpcRoot.OfficialServer.CalcConfigBinaryService.QueryCalcConfigsAsync(coinCodes, data => {
                     if (data != null && data.Count != 0) {

+ 0 - 6
src/NTMinerClient/Messages.cs

@@ -201,12 +201,6 @@ namespace NTMiner {
         public MaxTempChangedEvent() { }
     }
 
-    [MessageType(description: "收益计算器数据集初始化后")]
-    public class CalcConfigSetInitedEvent : EventBase {
-        public CalcConfigSetInitedEvent() {
-        }
-    }
-
     [MessageType(description: "从内核输出中提取了矿池延时")]
     public class PoolDelayPickedEvent : EventBase {
         public PoolDelayPickedEvent(Guid poolId, bool isDual, string poolDelay) {

+ 1 - 1
src/NTMinerDataSchemas/NTKeyword.cs

@@ -61,7 +61,7 @@ namespace NTMiner {
         public const int NTMinerDaemonPort = 3337;
 
         public const int MinerStudioPort = 3338;
-        public const string DNSServer0 = "119.29.29.29";
+        public const string DNSServer0 = "114.114.114.114";
         public const string DNSServer1 = "223.5.5.5";
         public const string MinerClientFinderFileName = "MinerClientFinder.exe";
         public const string AtikmdagPatcherFileName = "AtikmdagPatcher.exe";

+ 3 - 0
src/NTMinerDataSchemas/Ws/WsMessage.cs

@@ -69,6 +69,9 @@ namespace NTMiner.Ws {
         public const string SelfWorkLocalJson = "SelfWorkLocalJson";            // MinerClient->WsServer->Mq->WsServer->MinerStudio
         public const string GpuProfilesJson = "GpuProfilesJson";                // MinerClient->WsServer->Mq->WsServer->MinerStudio
 
+        public const string CalcConfigs = "CalcConfigs";                        // MinerClient->WsServer->MinerClient
+        public const string QueryCalcConfigs = "QueryCalcConfigs";              // MinerClient->WsServer->MinerClient
+
         /// <summary>
         /// WsServer收到来自MinerStudio的 <see cref="QueryClientDatas"/> WsMessage时往会Mq发送QueryClientsForWsRoutingKey消息,
         /// WebApiServer订阅了QueryClientsForWsRoutingKey消息并将QueryClientsForWsResponseMqMessage消息发送回到Mq,WsServer订阅了

+ 3 - 0
src/NTMinerNoDevFee/NTMinerNoDevFee.csproj

@@ -137,6 +137,9 @@
     <Compile Include="..\NTMinerlib\NTMinerException.cs">
       <Link>NTMinerException.cs</Link>
     </Compile>
+    <Compile Include="..\NTMinerlib\NTMinerHttpException.cs">
+      <Link>NTMinerHttpException.cs</Link>
+    </Compile>
     <Compile Include="..\NTMinerlib\NTMinerRegistry.cs">
       <Link>NTMinerRegistry.cs</Link>
     </Compile>

+ 4 - 6
src/NTMinerRpcClient/Core/Impl/KernelOutputKeywordSet.cs

@@ -128,14 +128,12 @@ namespace NTMiner.Core.Impl {
         }
 
         private const string fileName = "ServerKernelOutputKeywords.json";
-        private static readonly Func<string> GetFileId = () => {
-            return $"$/cache/{fileName}";
-        };
+        private static readonly string fileId = $"$/cache/{fileName}";
         private void CacheServerKernelOutputKeywords(List<KernelOutputKeywordData> data) {
             string json = VirtualRoot.JsonSerializer.Serialize(data);
             using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json))) {
                 using (LiteDatabase db = new LiteDatabase(_connectionString)) {
-                    db.FileStorage.Upload(GetFileId(), fileName, ms);
+                    db.FileStorage.Upload(fileId, fileName, ms);
                 }
             }
         }
@@ -143,9 +141,9 @@ namespace NTMiner.Core.Impl {
         private List<KernelOutputKeywordData> GetServerKernelOutputKeywordsFromCache() {
             try {
                 using (LiteDatabase db = new LiteDatabase(_connectionString)) {
-                    if (db.FileStorage.Exists(GetFileId())) {
+                    if (db.FileStorage.Exists(fileId)) {
                         using (MemoryStream ms = new MemoryStream()) {
-                            db.FileStorage.Download(GetFileId(), ms);
+                            db.FileStorage.Download(fileId, ms);
                             var json = Encoding.UTF8.GetString(ms.ToArray());
                             return VirtualRoot.JsonSerializer.Deserialize<List<KernelOutputKeywordData>>(json) ?? new List<KernelOutputKeywordData>();
                         }

+ 0 - 2
src/NTMinerRpcClient/NTMinerRpcClient.csproj

@@ -99,7 +99,6 @@
     <Compile Include="Services\Official\CalcConfigService.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Services\Official\KernelOutputKeywordService.cs" />
-    <Compile Include="Services\Official\ReportBinaryService.cs" />
     <Compile Include="Services\Official\ServerMessageBinaryService.cs" />
     <Compile Include="Services\Official\UserAppSettingService.cs" />
     <Compile Include="Services\Official\UserService.cs" />
@@ -107,7 +106,6 @@
     <Compile Include="Services\Official\ClientDataService.cs" />
     <Compile Include="Services\Official\UserMinerGroupService.cs" />
     <Compile Include="Services\Official\UserMineWorkService.cs" />
-    <Compile Include="Services\Official\ReportService.cs" />
     <Compile Include="Core\Impl\ServerMessageSet.cs" />
     <Compile Include="Services\OSSService.cs" />
     <Compile Include="Services\OSS\AliyunOSSService.cs" />

+ 4 - 1
src/NTMinerRpcClient/Rpc/Impl/BinaryRequestJsonResponseRpcHelper.cs

@@ -46,7 +46,10 @@ namespace NTMiner.Rpc.Impl {
                             });
                         }
                         else {
-                            callback?.Invoke(default, new NTMinerException($"{action} http response {getHttpResponse.Result.StatusCode.ToString()} {getHttpResponse.Result.ReasonPhrase}"));
+                            callback?.Invoke(default, new NTMinerHttpException($"{action} http response {getHttpResponse.Result.StatusCode.ToString()} {getHttpResponse.Result.ReasonPhrase}") {
+                                StatusCode = getHttpResponse.Result.StatusCode,
+                                ReasonPhrase = getHttpResponse.Result.ReasonPhrase
+                            });
                         }
                     }
                 }

+ 8 - 2
src/NTMinerRpcClient/Rpc/Impl/JsonRequestBinaryResponseRpcHelper.cs

@@ -38,7 +38,10 @@ namespace NTMiner.Rpc.Impl {
                             });
                         }
                         else {
-                            callback?.Invoke(default, new NTMinerException($"{action} http response {getHttpResponse.Result.StatusCode.ToString()} {getHttpResponse.Result.ReasonPhrase}"));
+                            callback?.Invoke(default, new NTMinerHttpException($"{action} http response {getHttpResponse.Result.StatusCode.ToString()} {getHttpResponse.Result.ReasonPhrase}") {
+                                StatusCode = getHttpResponse.Result.StatusCode,
+                                ReasonPhrase = getHttpResponse.Result.ReasonPhrase
+                            });
                         }
                     }
                 }
@@ -147,7 +150,10 @@ namespace NTMiner.Rpc.Impl {
                             });
                         }
                         else {
-                            callback?.Invoke(default, new NTMinerException($"{action} http response {getHttpResponse.Result.StatusCode.ToString()} {getHttpResponse.Result.ReasonPhrase}"));
+                            callback?.Invoke(default, new NTMinerHttpException($"{action} http response {getHttpResponse.Result.StatusCode.ToString()} {getHttpResponse.Result.ReasonPhrase}") {
+                                StatusCode = getHttpResponse.Result.StatusCode,
+                                ReasonPhrase = getHttpResponse.Result.ReasonPhrase
+                            });
                         }
                     }
                 }

+ 4 - 1
src/NTMinerRpcClient/Rpc/Impl/JsonRpcHelper.cs

@@ -38,7 +38,10 @@ namespace NTMiner.Rpc.Impl {
                             });
                         }
                         else {
-                            callback?.Invoke(default, new NTMinerException($"{action} http response {getHttpResponse.Result.StatusCode.ToString()} {getHttpResponse.Result.ReasonPhrase}"));
+                            callback?.Invoke(default, new NTMinerHttpException($"{action} http response {getHttpResponse.Result.StatusCode.ToString()} {getHttpResponse.Result.ReasonPhrase}") {
+                                StatusCode = getHttpResponse.Result.StatusCode,
+                                ReasonPhrase = getHttpResponse.Result.ReasonPhrase
+                            });
                         }
                     }
                 }

+ 4 - 1
src/NTMinerRpcClient/Rpc/Impl/JsonRpcHelper.partials.cs

@@ -104,7 +104,10 @@ namespace NTMiner.Rpc.Impl {
                             });
                         }
                         else {
-                            callback?.Invoke(default, new NTMinerException($"{action} http response {getHttpResponse.Result.StatusCode.ToString()} {getHttpResponse.Result.ReasonPhrase}"));
+                            callback?.Invoke(default, new NTMinerHttpException($"{action} http response {getHttpResponse.Result.StatusCode.ToString()} {getHttpResponse.Result.ReasonPhrase}") {
+                                StatusCode = getHttpResponse.Result.StatusCode,
+                                ReasonPhrase = getHttpResponse.Result.ReasonPhrase
+                            });
                         }
                     }
                 }

+ 0 - 22
src/NTMinerRpcClient/Services/Official/ReportBinaryService.cs

@@ -1,22 +0,0 @@
-using NTMiner.Controllers;
-using NTMiner.Report;
-using System;
-
-namespace NTMiner.Services.Official {
-    public class ReportBinaryService {
-        private readonly string _controllerName = ControllerUtil.GetControllerName<IReportBinaryController>();
-
-        internal ReportBinaryService() {
-        }
-
-        //public void ReportSpeedAsync(SpeedDto speedDto, Action<ReportResponse, Exception> callback) {
-        //    RpcRoot.BinaryRequestJsonResponseRpcHelper.PostAsync(
-        //        _controllerName, 
-        //        nameof(IReportBinaryController.ReportSpeed), 
-        //        query: null, 
-        //        speedDto, 
-        //        callback, 
-        //        timeountMilliseconds: 5000);
-        //}
-    }
-}

+ 0 - 35
src/NTMinerRpcClient/Services/Official/ReportService.cs

@@ -1,35 +0,0 @@
-using NTMiner.Controllers;
-using NTMiner.Report;
-using System;
-
-namespace NTMiner.Services.Official {
-    public class ReportService {
-        private readonly string _controllerName = ControllerUtil.GetControllerName<IReportController>();
-
-        internal ReportService() {
-        }
-
-        //public void ReportSpeedAsync(SpeedDto speedDto, Action<ReportResponse, Exception> callback) {
-        //    RpcRoot.JsonRpc.PostAsync(
-        //        _controllerName, 
-        //        nameof(IReportController.ReportSpeed), 
-        //        speedDto, 
-        //        callback, 
-        //        timeountMilliseconds: 5000);
-        //}
-
-        //public void ReportStateAsync(Guid clientId, bool isMining) {
-        //    ReportState request = new ReportState {
-        //        ClientId = clientId,
-        //        IsMining = isMining
-        //    };
-        //    RpcRoot.JsonRpc.FirePostAsync(
-        //        _controllerName, 
-        //        nameof(IReportController.ReportState), 
-        //        null, 
-        //        request, 
-        //        null, 
-        //        5000);
-        //}
-    }
-}

+ 0 - 2
src/NTMinerRpcClient/Services/OfficialServices.cs

@@ -12,8 +12,6 @@
         public readonly CalcConfigBinaryService CalcConfigBinaryService = new CalcConfigBinaryService();
         public readonly ServerMessageService ServerMessageService = new ServerMessageService();
         public readonly ServerMessageBinaryService ServerMessageBinaryService = new ServerMessageBinaryService();
-        public readonly ReportService ReportService = new ReportService();
-        public readonly ReportBinaryService ReportBinaryService = new ReportBinaryService();
         public readonly UserService UserService = new UserService();
         public readonly AppSettingService AppSettingService = new AppSettingService();
         public readonly UserAppSettingService UserAppSettingService = new UserAppSettingService();

+ 13 - 0
src/NTMinerServer/Core/IReadOnlyCalcConfigSet.cs

@@ -0,0 +1,13 @@
+using NTMiner.Core.MinerServer;
+using System.Collections.Generic;
+
+namespace NTMiner.Core {
+    public interface IReadOnlyCalcConfigSet {
+        /// <summary>
+        /// 读取给定币种列表的收益计算器数据
+        /// </summary>
+        /// <param name="coinCodes">null或长度0表示读取全部</param>
+        /// <returns></returns>
+        List<CalcConfigData> Gets(string[] coinCodes);
+    }
+}

+ 56 - 0
src/NTMinerServer/Core/Impl/ReadOnlyCalcConfigSet.cs

@@ -0,0 +1,56 @@
+using NTMiner.Core.MinerServer;
+using NTMiner.Core.Redis;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace NTMiner.Core.Impl {
+    public class ReadOnlyCalcConfigSet : IReadOnlyCalcConfigSet {
+        protected Dictionary<string, CalcConfigData> _dicByCode = new Dictionary<string, CalcConfigData>(StringComparer.OrdinalIgnoreCase);
+        protected readonly ICalcConfigDataRedis _redis;
+
+        public ReadOnlyCalcConfigSet(ICalcConfigDataRedis redis) {
+            _redis = redis;
+            VirtualRoot.BuildEventPath<Per10MinuteEvent>("周期从redis加载收益计算器配置数据", LogEnum.DevConsole, typeof(ReadOnlyCalcConfigSet), PathPriority.Normal, message => {
+                Load();
+            });
+            VirtualRoot.BuildEventPath<CalcConfigsUpdatedMqEvent>("收到CalcConfigsUpdated Mq消息后从redis加载数据刷新内存中的收益计算器数据集", LogEnum.DevConsole, typeof(ReadOnlyCalcConfigSet), PathPriority.Normal, message => {
+                Load();
+            });
+            Load().ContinueWith(t=> {
+                VirtualRoot.RaiseEvent(new CalcConfigSetInitedEvent());
+            });
+        }
+
+        protected Task Load() {
+            return _redis.GetAllAsync().ContinueWith(t => {
+                Dictionary<string, CalcConfigData> dicByCode = new Dictionary<string, CalcConfigData>(StringComparer.OrdinalIgnoreCase);
+                foreach (var item in t.Result) {
+                    dicByCode.Add(item.CoinCode, item);
+                }
+                _dicByCode = dicByCode;
+            });
+        }
+
+        /// <summary>
+        /// <see cref="ICalcConfigSet.Gets(IEnumerable{string})"/>
+        /// </summary>
+        /// <param name="coinCodes">null或长度0表示读取全部</param>
+        /// <returns></returns>
+        public List<CalcConfigData> Gets(string[] coinCodes) {
+            if (coinCodes == null || coinCodes.Length == 0) {
+                return _dicByCode.Values.ToList();
+            }
+            else {
+                List<CalcConfigData> list = new List<CalcConfigData>();
+                foreach (var coinCode in coinCodes) {
+                    if (_dicByCode.TryGetValue(coinCode, out CalcConfigData value)) {
+                        list.Add(value);
+                    }
+                }
+                return list;
+            }
+        }
+    }
+}

+ 5 - 0
src/NTMinerServer/Core/Messages.cs

@@ -543,4 +543,9 @@ namespace NTMiner.Core {
         public MqCountData Data { get; private set; }
         public DateTime Timestamp { get; private set; }
     }
+
+    [MessageType(description: "收到了CalcConfigsUpdated Mq消息后")]
+    public class CalcConfigsUpdatedMqEvent : EventBase {
+        public CalcConfigsUpdatedMqEvent() { }
+    }
 }

+ 18 - 0
src/NTMinerServer/Core/Mq/MqMessagePaths/CalcConfigMqMessagePath.cs

@@ -0,0 +1,18 @@
+using RabbitMQ.Client.Events;
+using System;
+using System.Collections.Generic;
+
+namespace NTMiner.Core.Mq.MqMessagePaths {
+    public class CalcConfigMqMessagePath : AbstractMqMessagePath<CalcConfigSetInitedEvent> {
+        public CalcConfigMqMessagePath(string queue) : base(queue) {
+        }
+
+        protected override Dictionary<string, Action<BasicDeliverEventArgs>> GetPaths() {
+            return new Dictionary<string, Action<BasicDeliverEventArgs>> {
+                [MqKeyword.CalcConfigsUpdatedRoutingKey] = ea => {
+                    VirtualRoot.RaiseEvent(new CalcConfigsUpdatedMqEvent());
+                }
+            };
+        }
+    }
+}

+ 10 - 0
src/NTMinerServer/Core/Redis/ICalcConfigDataRedis.cs

@@ -0,0 +1,10 @@
+using NTMiner.Core.MinerServer;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace NTMiner.Core.Redis {
+    public interface ICalcConfigDataRedis {
+        Task<CalcConfigData[]> GetAllAsync();
+        Task SetAsync(List<CalcConfigData> data);
+    }
+}

+ 48 - 0
src/NTMinerServer/Core/Redis/Impl/CalcConfigDataRedis.cs

@@ -0,0 +1,48 @@
+using NTMiner.Core.MinerServer;
+using StackExchange.Redis;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace NTMiner.Core.Redis.Impl {
+    public class CalcConfigDataRedis : ICalcConfigDataRedis {
+        protected const string _redisKeyCalcConfigs = RedisKeyword.CalcConfigs;
+
+        protected readonly IRedis _redis;
+        public CalcConfigDataRedis(IRedis redis) {
+            _redis = redis;
+        }
+
+        public Task<CalcConfigData[]> GetAllAsync() {
+            var db = _redis.GetDatabase();
+            return db.HashGetAllAsync(_redisKeyCalcConfigs).ContinueWith(t => {
+                List<CalcConfigData> list = new List<CalcConfigData>();
+                foreach (var item in t.Result) {
+                    if (item.Value.HasValue) {
+                        CalcConfigData data = VirtualRoot.JsonSerializer.Deserialize<CalcConfigData>(item.Value);
+                        if (data != null) {
+                            list.Add(data);
+                        }
+                    }
+                }
+                return list.ToArray();
+            });
+        }
+
+        public Task SetAsync(List<CalcConfigData> data) {
+            if (data == null || data.Count == 0) {
+                return TaskEx.CompletedTask;
+            }
+            var db = _redis.GetDatabase();
+            return db.HashKeysAsync(_redisKeyCalcConfigs).ContinueWith(t => {
+                foreach (var key in t.Result) {
+                    db.HashDelete(_redisKeyCalcConfigs, key);
+                }
+                List<HashEntry> entries = new List<HashEntry>();
+                foreach (var item in data) {
+                    entries.Add(new HashEntry(item.CoinCode, VirtualRoot.JsonSerializer.Serialize(item)));
+                }
+                db.HashSet(_redisKeyCalcConfigs, entries.ToArray());
+            });
+        }
+    }
+}

+ 1 - 0
src/NTMinerServer/MqKeyword.cs

@@ -46,5 +46,6 @@ namespace NTMiner {
         public const string StartWorkMineRoutingKey = WsMessage.StartWorkMine;
 
         public const string RefreshMinerTestIdRoutingKey = "RefreshMinerTestId";
+        public const string CalcConfigsUpdatedRoutingKey = "CalcConfigsUpdated";
     }
 }

+ 6 - 0
src/NTMinerServer/NTMinerServer.csproj

@@ -46,11 +46,14 @@
   <ItemGroup>
     <Compile Include="Core\IHostConfig.cs" />
     <Compile Include="Core\Impl\HostConfigData.cs" />
+    <Compile Include="Core\Impl\ReadOnlyCalcConfigSet.cs" />
     <Compile Include="Core\Impl\WsServerNodeAddressSetBase.cs" />
+    <Compile Include="Core\IReadOnlyCalcConfigSet.cs" />
     <Compile Include="Core\IWsServerNodeAddressSet.cs" />
     <Compile Include="Core\Mq\ClientIdIp.cs" />
     <Compile Include="Core\Mq\MqCountMqBodyUtil.cs" />
     <Compile Include="Core\Mq\MqMessagePaths\BasicDeliverEventArgsExtensions.cs" />
+    <Compile Include="Core\Mq\MqMessagePaths\CalcConfigMqMessagePath.cs" />
     <Compile Include="Core\Mq\MqMessagePaths\ClientTestIdMqMessagePath.cs" />
     <Compile Include="Core\Mq\Senders\Impl\MqCountSender.cs" />
     <Compile Include="Core\Mq\Senders\IMqCountSender.cs" />
@@ -61,8 +64,11 @@
     <Compile Include="Core\Mq\MqMessagePaths\AbstractMqMessagePath`3.cs" />
     <Compile Include="Core\Mq\MqMessagePaths\AbstractMqMessagePath`2.cs" />
     <Compile Include="Core\Mq\MqMessagePaths\ReadOnlyUserMqMessagePath.cs" />
+    <Compile Include="ReadOnlyCalcConfigSetExtensions.cs" />
+    <Compile Include="Core\Redis\ICalcConfigDataRedis.cs" />
     <Compile Include="Core\Redis\IClientTestIdDataRedis.cs" />
     <Compile Include="Core\Redis\IMinerDataRedis.cs" />
+    <Compile Include="Core\Redis\Impl\CalcConfigDataRedis.cs" />
     <Compile Include="Core\Redis\Impl\ClientTestIdDataRedis.cs" />
     <Compile Include="Core\Redis\Impl\MinerDataRedis.cs" />
     <Compile Include="Core\Redis\Impl\ReadOnlyWsServerNodeRedis.cs" />

+ 25 - 0
src/NTMinerServer/ReadOnlyCalcConfigSetExtensions.cs

@@ -0,0 +1,25 @@
+using NTMiner.Core;
+using NTMiner.Core.MinerServer;
+using System;
+using System.Collections.Generic;
+
+namespace NTMiner {
+    public static class ReadOnlyCalcConfigSetExtensions {
+        public static List<CalcConfigData> Gets(this IReadOnlyCalcConfigSet set, string coinCodes) {
+            try {
+                string[] coins;
+                if (string.IsNullOrEmpty(coinCodes)) {
+                    coins = new string[0];
+                }
+                else {
+                    coins = coinCodes?.Split(',');
+                }
+                return set.Gets(coins);
+            }
+            catch (Exception e) {
+                Logger.ErrorDebugLine(e);
+                return new List<CalcConfigData>();
+            }
+        }
+    }
+}

+ 4 - 0
src/NTMinerServer/RedisKeyword.cs

@@ -26,6 +26,10 @@
         /// </summary>
         public const string CaptchasCaptchaById = "captchas.CaptchaById";
         /// <summary>
+        /// 是个键值对,键是CoinCode
+        /// </summary>
+        public const string CalcConfigs = "calcConfigs";
+        /// <summary>
         /// 根据Id索引ActiveOn时间戳字符串,这个Id跟ClientData的Id是同一个Id。这里的时间戳字符串
         /// 不会经常更新但肯定会更新,因为这个时间戳的目的是为了周期发现用不活跃的记录从而删除掉。
         /// </summary>

+ 1 - 1
src/NTMinerWpf/Views/LocalIpConfig.xaml

@@ -93,7 +93,7 @@
                                     </GroupBox.Header>
                                     <StackPanel IsEnabled="{Binding IsAutoDNSServer, Converter={StaticResource BoolInvertConverter}}">
                                         <WrapPanel Margin="0 0 0 4">
-                                            <TextBlock Style="{StaticResource LblTb}" Text="首选 DNS(不填表示用腾讯的):"></TextBlock>
+                                            <TextBlock Style="{StaticResource LblTb}" Text="首选 DNS(不填表示用114的):"></TextBlock>
                                             <controls:IpAddressControl 
                                                 BorderThickness="1" 
                                                 BorderBrush="#666" 

+ 5 - 0
src/NTMinerlib/Messages.cs

@@ -305,4 +305,9 @@ namespace NTMiner {
     public class WsServerNodeAddressSetInitedEvent : EventBase {
         public WsServerNodeAddressSetInitedEvent() { }
     }
+
+    [MessageType(description: "收益计算器配置集已初始化完成")]
+    public class CalcConfigSetInitedEvent : EventBase {
+        public CalcConfigSetInitedEvent() { }
+    }
 }

+ 22 - 0
src/NTMinerlib/NTMinerHttpException.cs

@@ -0,0 +1,22 @@
+
+namespace NTMiner {
+    using System;
+    using System.Net;
+    using System.Runtime.Serialization;
+
+    public class NTMinerHttpException : Exception {
+        public NTMinerHttpException() : base() { }
+
+        public NTMinerHttpException(string message) : base(message) { }
+
+        public NTMinerHttpException(string message, Exception innerException) : base(message, innerException) { }
+
+        public NTMinerHttpException(string format, params object[] args) : base(string.Format(format, args)) { }
+
+        protected NTMinerHttpException(SerializationInfo info, StreamingContext context) : base(info, context) { }
+
+        public HttpStatusCode StatusCode { get; set; }
+
+        public string ReasonPhrase { get; set; }
+    }
+}

+ 1 - 0
src/NTMinerlib/NTMinerlib.csproj

@@ -58,6 +58,7 @@
     <Compile Include="IdGenerator\DefaultIdGenerator.cs" />
     <Compile Include="IdGenerator\IIdGenerator.cs" />
     <Compile Include="Net\Hosts.cs" />
+    <Compile Include="NTMinerHttpException.cs" />
     <Compile Include="NTMinerRegistry.partials.cs" />
     <Compile Include="Net\IpUtil.cs" />
     <Compile Include="Repositories\JsonReadOnlyRepository`1.cs" />

+ 5 - 2
src/WebApiServer/AppRoot.cs

@@ -59,6 +59,7 @@ namespace NTMiner {
                         string wsBreathQueue = queue + MqKeyword.WsBreathQueueEndsWith;
                         AbstractMqMessagePath[] mqMessagePaths = new AbstractMqMessagePath[] {
                             new UserMqMessagePath(durableQueue),
+                            new CalcConfigMqMessagePath(queue),
                             new MinerClientMqMessagePath(queue),
                             new WsBreathMqMessagePath(wsBreathQueue),
                             new OperationMqMessagePath(queue),
@@ -78,12 +79,14 @@ namespace NTMiner {
                         ClientTestIdDataRedis = new ClientTestIdDataRedis(redis);
                         var minerClientMqSender = new MinerClientMqSender(mq);
                         var userMqSender = new UserMqSender(mq);
+                        var calcConfigMqSender = new CalcConfigMqSender(mq);
 
                         var minerRedis = new MinerDataRedis(redis);
                         var clientActiveOnRedis = new ClientActiveOnRedis(redis);
                         var speedDataRedis = new SpeedDataRedis(redis);
                         var userRedis = new UserDataRedis(redis);
                         var captchaRedis = new CaptchaDataRedis(redis);
+                        var calcConfigRedis = new CalcConfigDataRedis(redis);
 
                         MqCountSet = new MqCountSet();
                         WsServerNodeRedis = new WsServerNodeRedis(redis);
@@ -91,12 +94,12 @@ namespace NTMiner {
                         UserSet = new UserSet(userRedis, userMqSender);
                         UserAppSettingSet = new UserAppSettingSet();
                         CaptchaSet = new CaptchaSet(captchaRedis);
-                        CalcConfigSet = new CalcConfigSet();
+                        CalcConfigSet = new CalcConfigSet(calcConfigRedis, calcConfigMqSender);
                         NTMinerWalletSet = new NTMinerWalletSet();
                         GpuNameSet = new GpuNameSet();
                         ClientDataSet clientDataSet = new ClientDataSet(minerRedis, clientActiveOnRedis, speedDataRedis, minerClientMqSender);
                         ClientDataSet = clientDataSet;
-                        var operationMqSender = new OperationMqSender(mqRedis);
+                        var operationMqSender = new OperationMqSender(mq);
                         MineWorkSet = new UserMineWorkSet(operationMqSender);
                         MinerGroupSet = new UserMinerGroupSet();
                         NTMinerFileSet = new NTMinerFileSet();

+ 1 - 15
src/WebApiServer/Controllers/CalcConfigController.cs

@@ -34,21 +34,7 @@ namespace NTMiner.Controllers {
         /// <param name="coinCodes"></param>
         /// <returns></returns>
         internal static DataResponse<List<CalcConfigData>> DoCalcConfigs(string coinCodes) {
-            try {
-                string[] coins;
-                if (string.IsNullOrEmpty(coinCodes)) {
-                    coins = new string[0];
-                }
-                else {
-                    coins = coinCodes?.Split(',');
-                }
-                var data = AppRoot.CalcConfigSet.Gets(coins);
-                return DataResponse<List<CalcConfigData>>.Ok(data);
-            }
-            catch (Exception e) {
-                Logger.ErrorDebugLine(e);
-                return ResponseBase.ServerError<DataResponse<List<CalcConfigData>>>(e.Message);
-            }
+            return DataResponse<List<CalcConfigData>>.Ok(AppRoot.CalcConfigSet.Gets(coinCodes));
         }
 
         #region SaveCalcConfigs

+ 0 - 19
src/WebApiServer/Controllers/ReportBinaryController.cs

@@ -1,19 +0,0 @@
-using NTMiner.Report;
-using System.Web.Http;
-
-namespace NTMiner.Controllers {
-    public class ReportBinaryController : ApiControllerBase, IReportBinaryController {
-        //[Role.Public]
-        //[HttpPost]
-        //public ReportResponse ReportSpeed() {
-        //    return new ReportResponse {
-        //        Description = "ignore",
-        //        ReasonPhrase = "ok",
-        //        StateCode = 200
-        //    };
-        //    //byte[] bytes = Request.Content.ReadAsByteArrayAsync().Result;
-        //    //SpeedDto speedDto = VirtualRoot.BinarySerializer.Deserialize<SpeedDto>(bytes);
-        //    //return ReportController.DoReportSpeed(speedDto, RemoteIp);
-        //}
-    }
-}

+ 0 - 56
src/WebApiServer/Controllers/ReportController.cs

@@ -1,56 +0,0 @@
-using NTMiner.Report;
-using System;
-using System.Web.Http;
-
-namespace NTMiner.Controllers {
-    // 注意该控制器不能重命名
-    public class ReportController : ApiControllerBase, IReportController {
-        //internal static ReportResponse DoReportSpeed(SpeedDto speedDto, string minerIp) {
-        //    try {
-        //        if (speedDto == null) {
-        //            return ResponseBase.InvalidInput<ReportResponse>();
-        //        }
-        //        AppRoot.ClientDataSet.ReportSpeed(speedDto, minerIp, isFromWsServerNode: false);
-        //        if (Version.TryParse(speedDto.Version, out Version version)) {
-        //            string jsonVersionKey = HomePath.GetServerJsonVersion(version);
-        //            var response = ReportResponse.Ok(AppRoot.GetServerStateResponse(jsonVersionKey));
-        //            if (speedDto.LocalServerMessageTimestamp.AddDays(1) > DateTime.Now // 为了排除Timestamp.UnixBaseTime
-        //                && speedDto.LocalServerMessageTimestamp.AddSeconds(1) < AppRoot.ServerMessageTimestamp) {
-        //                var list = AppRoot.ServerMessageSet.GetServerMessages(speedDto.LocalServerMessageTimestamp);
-        //                // 如果服务器新消息少于10条直接在上报算力时的响应消息中携带上,如果较多就算了推迟到用户切换到消息界面查看时再获取
-        //                if (list.Count < 10) {
-        //                    response.NewServerMessages.AddRange(list);
-        //                }
-        //            }
-        //            return response;
-        //        }
-        //    }
-        //    catch (Exception e) {
-        //        Logger.ErrorDebugLine(e);
-        //    }
-        //    return ResponseBase.InvalidInput<ReportResponse>();
-        //}
-
-        //[Role.Public]
-        //[HttpPost]
-        //public ReportResponse ReportSpeed([FromBody]SpeedDto speedDto) {
-        //    return new ReportResponse {
-        //        Description = "ignore",
-        //        ReasonPhrase = "ok",
-        //        StateCode = 200
-        //    };
-        //    //return DoReportSpeed(speedDto, RemoteIp);
-        //}
-
-        //[Role.Public]
-        //[HttpPost]
-        //public void ReportState([FromBody]ReportState request) {
-        //    try {
-        //        AppRoot.ClientDataSet.ReportState(request, RemoteIp, isFromWsServerNode: false);
-        //    }
-        //    catch (Exception e) {
-        //        Logger.ErrorDebugLine(e);
-        //    }
-        //}
-    }
-}

+ 1 - 7
src/WebApiServer/Core/ICalcConfigSet.cs

@@ -2,13 +2,7 @@
 using System.Collections.Generic;
 
 namespace NTMiner.Core {
-    public interface ICalcConfigSet {
-        /// <summary>
-        /// 读取给定币种列表的收益计算器数据
-        /// </summary>
-        /// <param name="coinCodes">null或长度0表示读取全部</param>
-        /// <returns></returns>
-        List<CalcConfigData> Gets(string[] coinCodes);
+    public interface ICalcConfigSet : IReadOnlyCalcConfigSet {
         void SaveCalcConfigs(List<CalcConfigData> data);
     }
 }

+ 11 - 57
src/WebApiServer/Core/Impl/CalcConfigSet.cs

@@ -1,68 +1,22 @@
-using LiteDB;
-using NTMiner.Core.MinerServer;
-using System;
+using NTMiner.Core.MinerServer;
+using NTMiner.Core.Mq.Senders;
+using NTMiner.Core.Redis;
 using System.Collections.Generic;
-using System.Linq;
 
 namespace NTMiner.Core.Impl {
-    public class CalcConfigSet : SetBase, ICalcConfigSet {
-        private Dictionary<string, CalcConfigData> _dicByCode = new Dictionary<string, CalcConfigData>(StringComparer.OrdinalIgnoreCase);
-
-        public CalcConfigSet() {
-        }
-
-        protected override void Init() {
-            using (LiteDatabase db = AppRoot.CreateLocalDb()) {
-                var col = db.GetCollection<CalcConfigData>();
-                foreach (var item in col.FindAll()) {
-                    _dicByCode.Add(item.CoinCode, item);
-                }
-            }
-        }
-
-        /// <summary>
-        /// <see cref="ICalcConfigSet.Gets(IEnumerable{string})"/>
-        /// </summary>
-        /// <param name="coinCodes">null或长度0表示读取全部</param>
-        /// <returns></returns>
-        public List<CalcConfigData> Gets(string[] coinCodes) {
-            InitOnece();
-            if (coinCodes == null || coinCodes.Length == 0) {
-                return _dicByCode.Values.ToList();
-            }
-            else {
-                List<CalcConfigData> list = new List<CalcConfigData>();
-                foreach (var coinCode in coinCodes) {
-                    if (_dicByCode.TryGetValue(coinCode, out CalcConfigData value)) {
-                        list.Add(value);
-                    }
-                }
-                return list;
-            }
+    public class CalcConfigSet : ReadOnlyCalcConfigSet, ICalcConfigSet {
+        private readonly ICalcConfigMqSender _mqSender;
+        public CalcConfigSet(ICalcConfigDataRedis redis, ICalcConfigMqSender mqSender) : base(redis) {
+            _mqSender = mqSender;
         }
 
         public void SaveCalcConfigs(List<CalcConfigData> data) {
-            InitOnece();
             if (data == null || data.Count == 0) {
                 return;
-            }
-            lock (_dicByCode) {
-                var dic = new Dictionary<string, CalcConfigData>(StringComparer.OrdinalIgnoreCase);
-                foreach (var item in data) {
-                    if (dic.TryGetValue(item.CoinCode, out CalcConfigData entity)) {
-                        entity.Update(item);
-                    }
-                    else {
-                        dic.Add(item.CoinCode, item);
-                    }
-                }
-                using (LiteDatabase db = AppRoot.CreateLocalDb()) {
-                    var col = db.GetCollection<CalcConfigData>();
-                    col.Delete(Query.All());
-                    col.Insert(dic.Values);
-                }
-                _dicByCode = dic;
-            }
+            }            
+            _redis.SetAsync(data).ContinueWith(t=> {
+                _mqSender.SendCalcConfigsUpdated();
+            });
         }
     }
 }

+ 5 - 0
src/WebApiServer/Core/Mq/Senders/ICalcConfigMqSender.cs

@@ -0,0 +1,5 @@
+namespace NTMiner.Core.Mq.Senders {
+    public interface ICalcConfigMqSender : IMqSender {
+        void SendCalcConfigsUpdated();
+    }
+}

+ 26 - 0
src/WebApiServer/Core/Mq/Senders/Impl/CalcConfigMqSender.cs

@@ -0,0 +1,26 @@
+using RabbitMQ.Client;
+
+namespace NTMiner.Core.Mq.Senders.Impl {
+    public class CalcConfigMqSender : ICalcConfigMqSender {
+        private static readonly byte[] _emptyBody = new byte[0];
+        private readonly IMq _mq;
+        public CalcConfigMqSender(IMq mq) {
+            _mq = mq;
+        }
+
+        public void SendCalcConfigsUpdated() {
+            _mq.BasicPublish(
+                routingKey: MqKeyword.CalcConfigsUpdatedRoutingKey,
+                basicProperties: CreateBasicProperties(),
+                body: _emptyBody);
+        }
+
+        private IBasicProperties CreateBasicProperties() {
+            var basicProperties = _mq.CreateBasicProperties();
+            basicProperties.Persistent = false;
+            basicProperties.Expiration = MqKeyword.Expiration60sec;
+
+            return basicProperties;
+        }
+    }
+}

+ 1 - 3
src/WebApiServer/SpecialPath.cs

@@ -2,13 +2,12 @@
 using System.IO;
 
 namespace NTMiner {
-    public static class SpecialPath {
+    public static partial class SpecialPath {
         static SpecialPath() {
             MineWorksDirFullName = Path.Combine(HomePath.AppDomainBaseDirectory, "MineWorks");
             if (!Directory.Exists(MineWorksDirFullName)) {
                 Directory.CreateDirectory(MineWorksDirFullName);
             }
-            LocalDbFileFullName = Path.Combine(HomePath.AppDomainBaseDirectory, NTKeyword.LocalDbFileName);
         }
 
         public static string GetMineWorkLocalJsonFileFullName(Guid workId) {
@@ -46,6 +45,5 @@ namespace NTMiner {
             return string.Empty;
         }
         public static string MineWorksDirFullName { get; private set; }
-        public static string LocalDbFileFullName { get; private set; }
     }
 }

+ 7 - 0
src/WebApiServer/SpecialPath.partials.cs

@@ -0,0 +1,7 @@
+using System.IO;
+
+namespace NTMiner {
+    public static partial class SpecialPath {
+        public static string LocalDbFileFullName { get; private set; } = Path.Combine(HomePath.AppDomainBaseDirectory, NTKeyword.LocalDbFileName);
+    }
+}

+ 3 - 2
src/WebApiServer/WebApiServer.csproj

@@ -100,7 +100,6 @@
     <Compile Include="Controllers\AdminController.cs" />
     <Compile Include="Controllers\CalcConfigBinaryController.cs" />
     <Compile Include="Controllers\NTMinerFileController.cs" />
-    <Compile Include="Controllers\ReportBinaryController.cs" />
     <Compile Include="Controllers\ServerMessageBinaryController.cs" />
     <Compile Include="Core\IGpuNameSet.cs" />
     <Compile Include="Core\IKernelOutputKeywordSet.cs" />
@@ -118,7 +117,9 @@
     <Compile Include="Core\Mq\MqMessagePaths\OperationMqMessagePath.cs" />
     <Compile Include="Core\Mq\MqMessagePaths\WsBreathMqMessagePath.cs" />
     <Compile Include="Core\Mq\Senders\IAdminMqSender.cs" />
+    <Compile Include="Core\Mq\Senders\ICalcConfigMqSender.cs" />
     <Compile Include="Core\Mq\Senders\Impl\AdminMqSender.cs" />
+    <Compile Include="Core\Mq\Senders\Impl\CalcConfigMqSender.cs" />
     <Compile Include="Core\Mq\Senders\Impl\OperationMqSender.cs" />
     <Compile Include="Core\Mq\Senders\IOperationMqSender.cs" />
     <Compile Include="Core\Redis\IClientActiveOnRedis.cs" />
@@ -145,7 +146,6 @@
     <Compile Include="Controllers\UserAppSettingController.cs" />
     <Compile Include="Controllers\UserController.cs" />
     <Compile Include="Controllers\OverClockDataController.cs" />
-    <Compile Include="Controllers\ReportController.cs" />
     <Compile Include="Controllers\WsServerNodeController.cs" />
     <Compile Include="Core\ICalcConfigSet.cs" />
     <Compile Include="Core\IClientDataSet.cs" />
@@ -174,6 +174,7 @@
     <Compile Include="Core\Redis\Impl\CaptchaDataRedis.cs" />
     <Compile Include="Core\Redis\Impl\UserDataRedis.cs" />
     <Compile Include="Core\Redis\IUserDataRedis.cs" />
+    <Compile Include="SpecialPath.partials.cs" />
     <Compile Include="UserDataExtensions.cs" />
     <Compile Include="AppRoot.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />

+ 21 - 17
src/WebApiServer/app.config

@@ -1,20 +1,24 @@
 <?xml version="1.0" encoding="utf-8"?>
 <configuration>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /></startup>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
-      </dependentAssembly>
-      <dependentAssembly>
-        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
-      </dependentAssembly>
-      <dependentAssembly>
-        <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
+	<startup>
+		<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
+	</startup>
+	<system.web>
+	</system.web>
+	<runtime>
+		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+			<dependentAssembly>
+				<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+				<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
+			</dependentAssembly>
+			<dependentAssembly>
+				<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
+				<bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
+			</dependentAssembly>
+			<dependentAssembly>
+				<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
+				<bindingRedirect oldVersion="0.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
+			</dependentAssembly>
+		</assemblyBinding>
+	</runtime>
 </configuration>

+ 15 - 8
src/WsServer/AppRoot.cs

@@ -25,6 +25,8 @@ namespace NTMiner {
             }
         }
 
+        public static IReadOnlyCalcConfigSet CalcConfigSet { get; private set; }
+
         public static IMinerClientSessionSet MinerClientSessionSet { get; private set; }
         public static IMinerStudioSessionSet MinerStudioSessionSet { get; private set; }
         public static IReadOnlyUserSet UserSet { get; private set; }
@@ -53,6 +55,7 @@ namespace NTMiner {
             string durableQueue = queue + MqKeyword.DurableQueueEndsWith;
             AbstractMqMessagePath[] mqMessagePaths = new AbstractMqMessagePath[] {
                 new ReadOnlyUserMqMessagePath(durableQueue),
+                new CalcConfigMqMessagePath(queue),
                 new MinerSignMqMessagePath(queue),
                 new WsServerNodeMqMessagePath(queue),
                 new OperationMqMessagePath(queue),
@@ -63,20 +66,24 @@ namespace NTMiner {
                 NTMinerConsole.UserError("启动失败,无法继续,因为服务器上下文创建失败");
                 return;
             }
-            MinerClientMqSender = new MinerClientMqSender(mqRedis);
-            SpeedDataRedis = new SpeedDataRedis(mqRedis);
-            WsServerNodeRedis = new WsServerNodeRedis(mqRedis);
-            OperationMqSender = new OperationMqSender(mqRedis);
-            UserMqSender = new UserMqSender(mqRedis);
-            _wsServerNodeMqSender = new WsServerNodeMqSender(mqRedis);
+            IRedis redis = mqRedis;
+            IMq mq = mqRedis;
+            MinerClientMqSender = new MinerClientMqSender(mq);
+            SpeedDataRedis = new SpeedDataRedis(redis);
+            WsServerNodeRedis = new WsServerNodeRedis(redis);
+            OperationMqSender = new OperationMqSender(mq);
+            UserMqSender = new UserMqSender(mq);
+            _wsServerNodeMqSender = new WsServerNodeMqSender(mq);
             WsServerNodeAddressSet = new WsServerNodeAddressSet(WsServerNodeRedis, _wsServerNodeMqSender);
-            var minerRedis = new MinerDataRedis(mqRedis);
-            var userRedis = new ReadOnlyUserDataRedis(mqRedis);
+            var minerRedis = new MinerDataRedis(redis);
+            var userRedis = new ReadOnlyUserDataRedis(redis);
+            var calcConfigRedis = new CalcConfigDataRedis(redis);
             VirtualRoot.StartTimer();
             // 构造函数中异步访问redis初始化用户列表,因为是异步的所以提前构造
             UserSet = new ReadOnlyUserSet(userRedis);
             MinerSignSet = new MinerSignSet(minerRedis);
             _wsServer = new SharpWsServerAdapter(ServerRoot.HostConfig);
+            CalcConfigSet = new ReadOnlyCalcConfigSet(calcConfigRedis);
             MinerClientSessionSet = new MinerClientSessionSet(_wsServer.MinerClientWsSessions);
             MinerStudioSessionSet = new MinerStudioSessionSet(_wsServer.MinerStudioWsSessions);
             _started = _wsServer.Start();

+ 1 - 2
src/WsServer/Core/ISession.cs

@@ -52,8 +52,7 @@ namespace NTMiner.Core {
         /// 或委托给<see cref="WebSocket.SendAsync(string, Action{bool})"/>。
         /// </summary>
         /// <param name="message"></param>
-        /// <param name="password"></param>
-        void SendAsync(WsMessage message, string password);
+        void SendAsync(WsMessage message);
         /// <summary>
         /// 将ActiveOn修置为当前时间。
         /// </summary>

+ 3 - 3
src/WsServer/Core/Impl/AbstractSession.cs

@@ -47,13 +47,13 @@ namespace NTMiner.Core.Impl {
             }
         }
 
-        public void SendAsync(WsMessage message, string password) {
+        public void SendAsync(WsMessage message) {
             if (TryGetWsSession(out IWsSessionAdapter wsSession)) {
                 if (WsUserName.IsBinarySupported) {
-                    wsSession.SendAsync(message.SignToBytes(password));
+                    wsSession.SendAsync(message.SignToBytes(this.GetSignPassword()));
                 }
                 else {
-                    wsSession.SendAsync(message.SignToJson(password));
+                    wsSession.SendAsync(message.SignToJson(this.GetSignPassword()));
                 }
             }
         }

+ 3 - 6
src/WsServer/Core/Impl/AbstractSessionSet`1.cs

@@ -65,12 +65,9 @@ namespace NTMiner.Core.Impl {
             }
             if (needReConnSessions.Count != 0) {
                 foreach (var session in needReConnSessions) {
-                    string password = session.GetSignPassword();
-                    if (!string.IsNullOrEmpty(password)) {
-                        session.SendAsync(new WsMessage(Guid.NewGuid(), WsMessage.ReGetServerAddress) {
-                            Data = hash.GetTargetNode(session.ClientId)
-                        }, password);
-                    }
+                    session.SendAsync(new WsMessage(Guid.NewGuid(), WsMessage.ReGetServerAddress) {
+                        Data = hash.GetTargetNode(session.ClientId)
+                    });
                 }
                 NTMinerConsole.DevWarn($"通知了 {needReConnSessions.Count.ToString()} 个Ws客户端重新连接");
             }

+ 1 - 2
src/WsServer/Core/Impl/MinerClientSessionSet.cs

@@ -276,8 +276,7 @@ namespace NTMiner.Core.Impl {
         public void SendToMinerClientAsync(Guid clientId, WsMessage message) {
             if (TryGetByClientId(clientId, out IMinerClientSession minerClientSession)) {
                 ServerRoot.IfMinerClientTestIdLogElseNothing(minerClientSession.ClientId, $"{nameof(WsMessage)}.{message.Type}");
-                string password = minerClientSession.GetSignPassword();
-                minerClientSession.SendAsync(message, password);
+                minerClientSession.SendAsync(message);
             }
         }
     }

+ 3 - 6
src/WsServer/Core/Impl/MinerStudioSessionSet.cs

@@ -176,12 +176,9 @@ namespace NTMiner.Core.Impl {
         public void SendToMinerStudioAsync(string loginName, WsMessage message) {
             // TODO:考虑给每一个登录的MinerStudio用户建立一个会话,由基于LoginName推送改为基于会话Id推送
             var minerStudioSessions = GetSessionsByLoginName(loginName).ToArray();// 避免发生集合被修改的异常
-            var userData = AppRoot.UserSet.GetUser(UserId.CreateLoginNameUserId(loginName));
-            if (userData != null) {
-                foreach (var minerStudioSession in minerStudioSessions) {
-                    ServerRoot.IfStudioClientTestIdLogElseNothing(minerStudioSession.ClientId, $"{nameof(WsMessage)}.{message.Type}");
-                    minerStudioSession.SendAsync(message, userData.Password);
-                }
+            foreach (var minerStudioSession in minerStudioSessions) {
+                ServerRoot.IfStudioClientTestIdLogElseNothing(minerStudioSession.ClientId, $"{nameof(WsMessage)}.{message.Type}");
+                minerStudioSession.SendAsync(message);
             }
         }
     }

+ 17 - 0
src/WsServer/WsMessageFromMinerClientHandler.cs

@@ -1,5 +1,6 @@
 using NTMiner.Core;
 using NTMiner.Core.MinerClient;
+using NTMiner.Core.MinerServer;
 using NTMiner.Core.Mq;
 using NTMiner.Report;
 using NTMiner.VirtualMemory;
@@ -97,6 +98,22 @@ namespace NTMiner {
                         ServerRoot.IfMinerClientTestIdLogElseNothing(clientId, $"{nameof(WsMessage)}.{message.Type}");
                         AppRoot.OperationMqSender.SendGpuProfilesJson(session.LoginName, clientId, json);
                     }
+                },
+                [WsMessage.CalcConfigs] = (session, clientId, message) => {
+                    ServerRoot.IfMinerClientTestIdLogElseNothing(clientId, $"{nameof(WsMessage)}.{message.Type}");
+                    List<CalcConfigData> data = AppRoot.CalcConfigSet.Gets(string.Empty);
+                    session.SendAsync(new WsMessage(Guid.NewGuid(), WsMessage.CalcConfigs) {
+                        Data = data
+                    });
+                },
+                [WsMessage.QueryCalcConfigs] = (session, clientId, message) => {
+                    if (message.TryGetData(out string coinCodes)) {
+                        ServerRoot.IfMinerClientTestIdLogElseNothing(clientId, $"{nameof(WsMessage)}.{message.Type}");
+                        List<CalcConfigData> data = AppRoot.CalcConfigSet.Gets(coinCodes);
+                        session.SendAsync(new WsMessage(Guid.NewGuid(), WsMessage.CalcConfigs) {
+                            Data = data
+                        });
+                    }
                 }
             };
 

+ 16 - 0
src/WsServer/WsMessageFromMinerStudioHandler.cs

@@ -184,6 +184,22 @@ namespace NTMiner {
                         ServerRoot.IfStudioClientTestIdLogElseNothing(studioId, $"{nameof(WsMessage)}.{message.Type}");
                         MqBufferRoot.AutoQueryClientDatas(QueryClientsForWsRequest.Create(query, session.LoginName, studioId, session.WsSessionId));
                     }
+                },
+                [WsMessage.CalcConfigs] = (session, clientId, message) => {
+                    ServerRoot.IfMinerClientTestIdLogElseNothing(clientId, $"{nameof(WsMessage)}.{message.Type}");
+                    List<CalcConfigData> data = AppRoot.CalcConfigSet.Gets(string.Empty);
+                    session.SendAsync(new WsMessage(Guid.NewGuid(), WsMessage.CalcConfigs) {
+                        Data = data
+                    });
+                },
+                [WsMessage.QueryCalcConfigs] = (session, clientId, message) => {
+                    if (message.TryGetData(out string coinCodes)) {
+                        ServerRoot.IfMinerClientTestIdLogElseNothing(clientId, $"{nameof(WsMessage)}.{message.Type}");
+                        List<CalcConfigData> data = AppRoot.CalcConfigSet.Gets(coinCodes);
+                        session.SendAsync(new WsMessage(Guid.NewGuid(), WsMessage.CalcConfigs) {
+                            Data = data
+                        });
+                    }
                 }
             };
 

+ 3 - 0
src/WsServer/WsServer.csproj

@@ -78,6 +78,9 @@
     <Reference Include="System.Web" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="..\WebApiServer\SpecialPath.partials.cs">
+      <Link>SpecialPath.partials.cs</Link>
+    </Compile>
     <Compile Include="Core\IMinerSignSet.cs" />
     <Compile Include="Core\Impl\MinerSignSet.cs" />
     <Compile Include="Core\Impl\WsServerNodeAddressSet.cs" />