Example #1
0
        public async Task GlobalFiltersRunBeforeHubSpecificFilters()
        {
            using (StartVerifiableLog())
            {
                var syncPoint1      = SyncPoint.Create(3, out var syncPoints1);
                var syncPoint2      = SyncPoint.Create(3, out var syncPoints2);
                var serviceProvider = HubConnectionHandlerTestUtils.CreateServiceProvider(services =>
                {
                    services.AddSignalR(options =>
                    {
                        options.AddFilter(new SyncPointFilter(syncPoints1));
                    })
                    .AddHubOptions <MethodHub>(options =>
                    {
                        options.AddFilter(new SyncPointFilter(syncPoints2));
                    });
                }, LoggerFactory);

                var connectionHandler = serviceProvider.GetService <HubConnectionHandler <MethodHub> >();

                using (var client = new TestClient())
                {
                    var connectionHandlerTask = await client.ConnectAsync(connectionHandler);

                    await syncPoints1[0].WaitForSyncPoint().OrTimeout();
                    // Second filter wont run yet because first filter is waiting on SyncPoint
                    Assert.False(syncPoints2[0].WaitForSyncPoint().IsCompleted);
                    syncPoints1[0].Continue();

                    await syncPoints2[0].WaitForSyncPoint().OrTimeout();
                    syncPoints2[0].Continue();
                    await client.Connected.OrTimeout();

                    var invokeTask = client.InvokeAsync(nameof(MethodHub.Echo), "Hello world!");

                    await syncPoints1[1].WaitForSyncPoint().OrTimeout();
                    // Second filter wont run yet because first filter is waiting on SyncPoint
                    Assert.False(syncPoints2[1].WaitForSyncPoint().IsCompleted);
                    syncPoints1[1].Continue();

                    await syncPoints2[1].WaitForSyncPoint().OrTimeout();
                    syncPoints2[1].Continue();
                    var message = await invokeTask.OrTimeout();

                    Assert.Null(message.Error);

                    client.Dispose();

                    await syncPoints1[2].WaitForSyncPoint().OrTimeout();
                    // Second filter wont run yet because first filter is waiting on SyncPoint
                    Assert.False(syncPoints2[2].WaitForSyncPoint().IsCompleted);
                    syncPoints1[2].Continue();

                    await syncPoints2[2].WaitForSyncPoint().OrTimeout();
                    syncPoints2[2].Continue();

                    await connectionHandlerTask.OrTimeout();
                }
            }
        }
Example #2
0
        public async Task SerializingTwoMessagesFromTheSameProtocolSimultaneouslyResultsInOneCachedItemAsync(int numberOfSerializationsToPreCache)
        {
            var invocation = new InvocationMessage("Foo", new object[0]);
            var message    = new SerializedHubMessage(invocation);

            // "Pre-cache" the requested number of serializations (so we can test scenarios involving each of the fields and the fallback list)
            for (var i = 0; i < numberOfSerializationsToPreCache; i++)
            {
                _ = message.GetSerializedMessage(new DummyHubProtocol($"p{i}"));
            }

            var onWrite  = SyncPoint.Create(2, out var syncPoints);
            var protocol = new DummyHubProtocol("test", () => onWrite().Wait());

            // Serialize once, but hold at the Hub Protocol
            var   firstSerialization = Task.Run(() => message.GetSerializedMessage(protocol));
            await syncPoints[0].WaitForSyncPoint();

            // Serialize again, which should hit the lock
            var secondSerialization = Task.Run(() => message.GetSerializedMessage(protocol));

            Assert.False(secondSerialization.IsCompleted);

            // Release both instances of the syncpoint
            syncPoints[0].Continue();
            syncPoints[1].Continue();

            // Everything should finish and only one serialization should be written
            await firstSerialization.DefaultTimeout();

            await secondSerialization.DefaultTimeout();

            Assert.Collection(message.GetAllSerializations().Skip(numberOfSerializationsToPreCache).ToArray(),
                              serializedMessage =>
            {
                Assert.Equal("test", serializedMessage.ProtocolName);
                Assert.Equal(DummyHubProtocol.DummySerialization, serializedMessage.Serialized.ToArray());
            });
        }