小编ksp*_*rin的帖子

多数据库同步 - SignalR与消息背板

问题

我的申请表如下:

  • 多个(<20)设备客户端(Android)在单个位置运行.
  • 存在数千个位置(因此存在数十或数十万个设备客户端).
  • 还存在一个门户网站客户端,它与每个位置的数据及其设备客户端同步工作.
  • 设备上生成的新数据通过REST API(ASP.net WebAPI)发布到服务器(云).

到目前为止,该应用程序是一个非常标准的应用程序,具有移动设备客户端和Web门户客

但是,由于每个设备客户端的要求不受我的控制(设备客户端需要在脱机模式下运行,减少网络延迟等),每个设备客户端不会使用服务器数据库作为其直接记录源.每个设备客户端都有自己的本地数据库(SQLite),该数据库与其所在位置的所有数据保持同步.例如:当我在设备客户端A上进行数据更改时,该更改需要传播到设备客户端B和Web门户客户端C.

  • Web门户客户端直接从服务器数据库读取,因为它不需要脱机功能.

正如您所看到的,这里的问题是我们现在需要一种方法来使所有设备客户端数据库实时保持同步.预计两个设备客户端之间的数据短暂延迟并且认为是正常的.

提出的解决方案

我提出的解决方案如下:

  • 当新客户端设备最初联机时,它会收到自上次从服务器通过REST API上线以来错过的数据转储.
  • 通过REST API从客户端设备发布/更新/删除的每个新数据项都传播到服务器数据库.服务器数据库包含所有位置的所有数据,应被视为永久记录源.
  • Web门户直接与服务器数据库一起工作,因为它没有脱机类型要求.
  • 通过SignalR建立到每个客户端设备到数据同步流服务的连接.
  • 工作服务正在"拖尾"服务器数据库以进行新的创建/更新/删除操作.检测到CUD操作时,会为每个数据同步服务实例将消息分派到Azure Service Bus队列/订阅(通过扇出主题).这允许SignalR数据同步服务(使用Azure Service Bus背板)的水平扩展,因为将存在数千个设备客户端连接.
  • 数据同步服务从其消息队列/订阅中读取,并通过SignalR将同步消息(包含所有需要的同步数据)推送到所有连接的客户端设备(用于与数据相关的位置).

下图说明了此解决方案:

提出的解决方案

  • 大块描绘服务器(灰色方块是可以水平缩放的HTTP Web服务器)
  • 箭头描绘了流经应用程序的数据的方向.

问题

  1. SignalR是解决此问题/解决方案的正确技术吗?最初我的解决方案涉及每个客户端设备建立自己的Azure Service Bus队列/订阅,该队列/订阅从数据库尾部工作者(sync river)收集消息.该解决方案的问题在于,我会将大量浪费的消息推送到离线设备客户端,这些客户端可能不会在很长一段时间内重新联机,如果有的话.通过在设备客户端最初联机时转储增量数据,然后通过SignalR流式传输数据,我可以解决这个问题.
  2. 我之前没有在生产环境中广泛使用SignalR,所以我对它有点新意.对于此解决方案,我可以期待遇到哪些问题/挑战?
  3. 以下文章指出"在某些情况下背板可能成为瓶颈.以下是一些典型的SignalR场景:高频实时(例如,实时游戏):不建议在这种情况下使用背板." 这个解决方案会属于这一类吗?Azure Service Bus消息的背板会引入哪些问题?如果不是这样,我还能如何扩展这个解决方案呢?

您也欢迎并赞赏您对此解决方案的一般意见和建议.

architecture asp.net scalability signalr

7
推荐指数
1
解决办法
1000
查看次数

模拟方法执行时间和顺序

我正在使用Moq与方法接口配对.我需要测试这个接口中的方法是按照一定的顺序执行的,也是每个方法执行一定次数的.

接口

public interface IInterface
{
    void MethodOne(string foo);
    void MethodTwo(string foo);
}
Run Code Online (Sandbox Code Playgroud)

方法

// MyClass stuff ...

public async Task Run()
{
    MethodOne("foo");
    MethodTwo("foo");
}

// ...
Run Code Online (Sandbox Code Playgroud)

测试

我写了这个测试来验证方法只执行了一定次数(一次):

[TestMethod]
public async Task Test()
{
    var mock = new Mock<IInterface>();
    var mockSequence = new MockSequence();

    var obj = new MyClass();
    await obj.Run();

    mock.Verify(i=> i.MethodOne("foo"), Times.Once());
    mock.Verify(i=> i.MethodTwo("foo"), Times.Once());
}
Run Code Online (Sandbox Code Playgroud)

这很好......

我已经尝试过这些测试来确定某个序列是否得到了适当的满足,但测试似乎总是通过.

[TestMethod]
public async Task Test()
{
    var mock = new Mock<IInterface>();
    var mockSequence = new MockSequence();

    var obj …
Run Code Online (Sandbox Code Playgroud)

.net c# moq

6
推荐指数
2
解决办法
2160
查看次数

为什么不总是配置最大数量的事件中心分区?

Azure的事件概述枢纽条规定如下:

分区数在事件中心创建时指定,并且必须介于8和32之间.分区是一种数据组织机制,与使用应用程序所需的下游并行度相关,而不是与事件中心吞吐量相关.这使得Event Hub中分区数量的选择与您期望拥有的并发读取器数量直接相关.创建事件中心后,分区计数不可更改; 您应该根据长期预期规模来考虑这个数字.您可以通过联系Azure Service Bus团队来增加32分区限制.

由于在初始创建后无法更改事件中心上的分区数,为什么不总是将其配置为最大分区数,32?这样做我没有看到任何定价影响.有一些表现权衡吗?

另外,作为另一方面,我似乎能够创建一个少于8个分区的事件中心.文章说它必须在8-32之间.不知道为什么会这么说......

azure azureservicebus azure-eventhub

6
推荐指数
1
解决办法
1282
查看次数

默认情况下,提供静态文件index.html

我有一个非常简单的角度应用程序项目,只需要提供静态文件wwwroot.这是我的Startup.cs:

public class Startup
{
    public void ConfigureServices(IServiceCollection services) { }

    public void Configure(IApplicationBuilder app)
    {
        app.UseIISPlatformHandler();
        app.UseStaticFiles();
    }

    // Entry point for the application.
    public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}
Run Code Online (Sandbox Code Playgroud)

每当我使用IIS Express或Web启动项目时,我总是必须导航到/index.html.我怎么做到这一点,我可以访问root(/)仍然得到index.html

asp.net asp.net-core

6
推荐指数
2
解决办法
2008
查看次数

基准测试WebCrypto比第三方库慢得多?

我正在评估WebCrypto性能与第三方加密库SJCLForge的比较.我希望WebCrypto 更快,因为它是本机浏览器实现.这也已经过基准测试并且已经显示出来.

我使用Benchmark.js实现了以下测试来测试密钥派生(PBKDF2-SHA256),加密(AES-CBC)和解密(AES-CBC).这些测试显示web加密速度明显慢于SJCL和Forge加密/解密.

基准代码

请看这里的小提琴:https://jsfiddle.net/kspearrin/1Lzvpzkz/

var iterations = 5000;
var keySize = 256;

sjcl.beware['CBC mode is dangerous because it doesn\'t protect message integrity.']();

// =========================================================
// Precomputed enc values for decrypt benchmarks
// =========================================================

var encIv = 'FX7Y3pYmcLIQt6WrKc62jA==';
var encCt = 'EDlxtzpEOfGIAIa8PkCQmA==';

// =========================================================
// Precomputed keys for benchmarks
// =========================================================

function sjclMakeKey() {
  return sjcl.misc.pbkdf2('mypassword', 'a salt', iterations, keySize, null);
}

var sjclKey = sjclMakeKey();

function forgeMakeKey() …
Run Code Online (Sandbox Code Playgroud)

javascript encryption sjcl benchmark.js webcrypto-api

6
推荐指数
1
解决办法
1096
查看次数

无法为 Rfc2898DeriveBytes 指定 4 个参数(哈希算法名称)

根据此处的文档,我应该能够Rfc2898DeriveBytes使用自定义哈希算法(在我的例子中为 SHA256)创建:

public Rfc2898DeriveBytes (byte[] password, byte[] salt, int iterations, System.Security.Cryptography.HashAlgorithmName hashAlgorithm);
Run Code Online (Sandbox Code Playgroud)

我创建了一个 .NET Standard 2.0 类库,其中包含以下内容:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

</Project>
Run Code Online (Sandbox Code Playgroud)

我的课

private static byte[] Pbkdf2(string data)
{
    // ...
    using(var pbkdf2 = new Rfc2898DeriveBytes(null, null, 50000, HashAlgorithmName.SHA256))
    {
        return pbkdf2.GetBytes(32);
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

“Rfc2898DeriveBytes”不包含带有 4 个参数的构造函数

为什么我不能将哈希算法添加到 的构造函数中Rfc2898DeriveBytes

c# .net-core .net-standard

6
推荐指数
1
解决办法
1896
查看次数

在Knockout中初始化时调用组件功能

使用普通的视图模型,我可以在它的上下文之外的初始化之后调用一个函数,如下所示:

var ViewModel = function () {
    this.Foo = function () {
        alert("bar");
    };
};

var vm = new ViewModel();
ko.applyBindings(vm);

vm.Foo();
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/h01ky3pv/

如何使用组件的视图模型执行此类操作?我想打电话FooComponentViewModelFoo功能,首先加载foo的组件时.

ko.components.register("foo", {
    viewModel: FooComponentViewModel,
    template: {
        element: "component-foo"
    }
});

function FooComponentViewModel(params) {
    this.Foo = function () {
        alert("bar");
    };
}

var ViewModel = function () {
    // empty
};

var vm = ViewModel();
ko.applyBindings();
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/r3d41q6c/2/

javascript knockout.js knockout-components

5
推荐指数
1
解决办法
2354
查看次数

JSON_MODIFY 删除数组对象

如何从VARCHAR(MAX)JSON 数组中删除对象?

设置

DECLARE @Json VARCHAR(MAX) =
JSON_QUERY('[{"u":"user1","i":"item1"},{"u":"user2","i":"item2"}]')

SELECT @Json

DECLARE @NewJson VARCHAR(MAX) =
JSON_QUERY('{"u":"user3","i":"item3"}')

SELECT @NewJson
Run Code Online (Sandbox Code Playgroud)

结果

[{"u":"user1","i":"item1"},{"u":"user2","i":"item2"}]

{"u":"user3","i":"item3"}
Run Code Online (Sandbox Code Playgroud)

附加@NewJson@Json

SELECT JSON_MODIFY(@Json, 'append $', JSON_QUERY(@NewJson))
Run Code Online (Sandbox Code Playgroud)

结果

[{"u":"user1","i":"item1"},{"u":"user2","i":"item2"},{"u":"user3","i":"item3"}]
Run Code Online (Sandbox Code Playgroud)

都好。

0从中删除索引@Json

SELECT JSON_MODIFY(@Json, '$[0]', NULL)
Run Code Online (Sandbox Code Playgroud)

结果

[null,{"u":"user2","i":"item2"}]
Run Code Online (Sandbox Code Playgroud)

我不希望索引0为空。我想把它去掉。

我在文档中找不到任何说明如何从数组中删除对象的内容。

sql t-sql sql-server

5
推荐指数
1
解决办法
3575
查看次数

如何从模拟器启动中删除`-no-boot-anim`标志?

我正在使用VS 15.4预览2来测试Android 8.0的一些东西.我试图将我的应用程序启动(调试)到AVD模拟器中,但是在打开后我在模拟器窗口中得到一个空白的黑屏.

我注意到从VS输出打开模拟器的命令是:

2>Starting emulator AVD_Nexus_5_L26 ...
2>C:\PROGRA~2\Android\ANDROI~1\tools\emulator.EXE -partition-size 512 -no-boot-anim -avd AVD_Nexus_5_L26 -prop monodroid.avdname=AVD_Nexus_5_L26
2>Hax is enabled
2>Hax ram_size 0x80000000
2>HAX is working and emulator runs in fast virt mode.
2>emulator: Listening for console connections on port: 5554
2>emulator: Serial number of this emulator (for ADB): emulator-5554
Run Code Online (Sandbox Code Playgroud)

我尝试emulator.EXE在CMD提示符中运行命令,我遇到了同样的问题.

将命令更改为(删除-no-boot-anim标志)后

C:\PROGRA~2\Android\ANDROI~1\tools\emulator.EXE -partition-size 512 -avd AVD_Nexus_5_L26 -prop monodroid.avdname=AVD_Nexus_5_L26
Run Code Online (Sandbox Code Playgroud)

模拟器从CMD提示符启动正常.

在尝试从VS中调试应用程序时,我是否知道如何从模拟器启动中删除此标志?即使我尝试在调试之前手动打开模拟器VS仍然关闭它并打开带有-no-boot-anim标志的新实例.

xamarin.android xamarin

5
推荐指数
0
解决办法
248
查看次数

decimal.ToString("C") 在 Linux 上产生 ¤ 货币符号

我有一个 ASP.NET Core 2.1 项目,我正在通过 Razor HTML 页面呈现一些货币数字。

查看模型

class MyModel
{
    public decimal Money { get; set; } = 1.23
}
Run Code Online (Sandbox Code Playgroud)

剃刀页

@model MyModel
<p>@Model.Money.ToString("C")</p>
Run Code Online (Sandbox Code Playgroud)

此项目部署到 Azure 应用服务。

在 Windows 应用服务计划(和我的本地 Windows 10 机器)上,这会按预期产生“1.23 美元”。但是,如果我将同一个项目部署到 Linux 应用服务计划,它会呈现“¤1.23”。

根据谷歌的说法:

货币符号 (¤) 是用于表示未指定货币的字符。

知道这两个操作系统之间有什么区别吗?我是否需要在 Linux 上明确设置文化或其他内容?

c# razor .net-core asp.net-core

5
推荐指数
1
解决办法
1136
查看次数