Cleanup and shuffling things

- Moved the InvocationAdapterRegistry registration to SignalROptions
- Moved the JsonNetInvocationAdapter to Microsoft.AspNetCore.SignalR
- Remove dead JavaScript code
This commit is contained in:
David Fowler 2016-11-02 20:54:58 -07:00
parent 8dd61250f4
commit b6f15338eb
12 changed files with 73 additions and 218 deletions

View File

@ -1,32 +0,0 @@
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
namespace ChatSample
{
public static class RpcExtensions
{
public static IApplicationBuilder UseRpc(this IApplicationBuilder app, Action<RpcBuilder> registerAdapters)
{
var adapters = app.ApplicationServices.GetRequiredService<InvocationAdapterRegistry>();
registerAdapters(new RpcBuilder(adapters));
return app;
}
}
public class RpcBuilder
{
private InvocationAdapterRegistry _invocationAdapters;
public RpcBuilder(InvocationAdapterRegistry invocationAdapters)
{
_invocationAdapters = invocationAdapters;
}
public void AddInvocationAdapter(string format, IInvocationAdapter adapter)
{
_invocationAdapters.RegisterInvocationAdapter(format, adapter);
}
}
}

View File

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ChatSample.Data;
using ChatSample.Hubs;
using ChatSample.Models;
using ChatSample.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
@ -9,11 +9,6 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using ChatSample.Data;
using ChatSample.Models;
using ChatSample.Services;
using ChatSample.Hubs;
using ChatSample;
namespace ChatSample
{
@ -56,6 +51,7 @@ namespace ChatSample
services.AddTransient<ISmsSender, AuthMessageSender>();
services.AddSignalR();
services.AddAuthentication();
}
@ -84,12 +80,7 @@ namespace ChatSample
app.UseSignalR(routes =>
{
routes.MapHub<Chat>("/hubs");
});
app.UseRpc(invocationAdapters =>
{
invocationAdapters.AddInvocationAdapter("json", new JsonNetInvocationAdapter());
routes.MapHub<Chat>("/chat");
});
app.UseMvc(routes =>

View File

@ -2,87 +2,10 @@
ViewData["Title"] = "Chat";
}
@*<link rel="stylesheet" href="~/css/chat.css" />*@
<script src="~/js/signalr-client.js"></script>
<script>
function hubConnection(url) {
var ws = new WebSocket(url);
var id = 0;
var calls = {};
var methods = {};
ws.onopen = function () {
console.log('Opened!');
};
ws.onmessage = function (event) {
let response = {};
//if (document.getElementById('formatType').value == 'line') {
// let parts = event.data.split(',');
// if (event.data[0] == 'R') {
// response.Id = parts[0].slice(2);
// response.Result = parts[1].slice(1);
// }
// else if (event.data[0] == 'C') {
// response.Method = parts[1].slice(1);
// response.Arguments = parts.slice(2).join();
// }
// else {
// response.error = parts[0].slice(1);
// }
//}
//else {
response = JSON.parse(event.data);
//}
// Response
if (response.Id) {
var cb = calls[response.Id];
delete calls[response.Id];
if (response.Error) {
cb.error(response.Error);
}
else {
cb.success(response.Result);
}
}
else {
// Reverse JSON RPC
methods[response.Method](response.Arguments);
}
};
ws.onclose = function (event) {
console.log('Closed!');
};
this.invoke = function (method, args, formatType) {
return new Promise((resolve, reject) => {
calls[id] = { success: resolve, error: reject };
if (formatType == 'line') {
ws.send(`CI${id},M${method},${args.join()}\n`);
}
else {
ws.send(JSON.stringify({ method: method, arguments: args, id: id }));
}
id++;
});
};
this.on = function (method, fn) {
methods[method] = fn;
};
}
document.addEventListener('DOMContentLoaded', () => {
let connection = new RpcConnection(`http://${document.location.host}/hubs`, 'formatType=json&format=text');
let connection = new RpcConnection(`http://${document.location.host}/chat`, 'formatType=json&format=text');
connection.on('Send', function (message) {
var child = document.createElement('li');

View File

@ -1,32 +0,0 @@
using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.DependencyInjection;
namespace SocketsSample
{
public static class RpcExtensions
{
public static IApplicationBuilder UseRpc(this IApplicationBuilder app, Action<RpcBuilder> registerAdapters)
{
var adapters = app.ApplicationServices.GetRequiredService<InvocationAdapterRegistry>();
registerAdapters(new RpcBuilder(adapters));
return app;
}
}
public class RpcBuilder
{
private InvocationAdapterRegistry _invocationAdapters;
public RpcBuilder(InvocationAdapterRegistry invocationAdapters)
{
_invocationAdapters = invocationAdapters;
}
public void AddInvocationAdapter(string format, IInvocationAdapter adapter)
{
_invocationAdapters.RegisterInvocationAdapter(format, adapter);
}
}
}

View File

@ -1,42 +0,0 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Newtonsoft.Json;
namespace SocketsSample
{
public class JsonNetInvocationAdapter : IInvocationAdapter
{
private JsonSerializer _serializer = new JsonSerializer();
public JsonNetInvocationAdapter()
{
}
public async Task<InvocationDescriptor> ReadInvocationDescriptor(Stream stream, Func<string, Type[]> getParams)
{
var reader = new JsonTextReader(new StreamReader(stream));
return await Task.Run(() => _serializer.Deserialize<InvocationDescriptor>(reader));
}
public Task WriteInvocationResult(InvocationResultDescriptor resultDescriptor, Stream stream)
{
Write(resultDescriptor, stream);
return Task.FromResult(0);
}
public Task WriteInvocationDescriptor(InvocationDescriptor invocationDescriptor, Stream stream)
{
Write(invocationDescriptor, stream);
return Task.FromResult(0);
}
private void Write(object value, Stream stream)
{
var writer = new JsonTextWriter(new StreamWriter(stream));
_serializer.Serialize(writer, value);
writer.Flush();
}
}
}

View File

@ -16,8 +16,16 @@ namespace SocketsSample
{
services.AddRouting();
services.AddSignalR();
// .AddRedis();
services.AddSingleton<ProtobufInvocationAdapter>();
services.AddSingleton<LineInvocationAdapter>();
services.AddSignalR()
.AddSignalROptions(options =>
{
options.RegisterInvocationAdapter<ProtobufInvocationAdapter>("protobuf");
options.RegisterInvocationAdapter<LineInvocationAdapter>("line");
});
// .AddRedis();
services.AddSingleton<ChatEndPoint>();
services.AddSingleton<ProtobufSerializer>();
@ -45,13 +53,6 @@ namespace SocketsSample
routes.MapSocketEndpoint<ChatEndPoint>("/chat");
routes.MapSocketEndpoint<RpcEndpoint<Echo>>("/jsonrpc");
});
app.UseRpc(invocationAdapters =>
{
invocationAdapters.AddInvocationAdapter("protobuf", new ProtobufInvocationAdapter(app.ApplicationServices));
invocationAdapters.AddInvocationAdapter("json", new JsonNetInvocationAdapter());
invocationAdapters.AddInvocationAdapter("line", new LineInvocationAdapter());
});
}
}
}

View File

@ -1,8 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.DependencyInjection
{
@ -14,9 +13,17 @@ namespace Microsoft.Extensions.DependencyInjection
services.AddSingleton(typeof(IHubContext<>), typeof(HubContext<>));
services.AddSingleton(typeof(HubEndPoint<>), typeof(HubEndPoint<>));
services.AddSingleton(typeof(RpcEndpoint<>), typeof(RpcEndpoint<>));
services.AddSingleton<IConfigureOptions<SignalROptions>, SignalROptionsSetup>();
services.AddSingleton<JsonNetInvocationAdapter>();
services.AddSingleton<InvocationAdapterRegistry>();
return new SignalRBuilder(services);
}
public static ISignalRBuilder AddSignalROptions(this ISignalRBuilder builder, Action<SignalROptions> configure)
{
builder.Services.Configure(configure);
return builder;
}
}
}

View File

@ -1,22 +1,29 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.SignalR
{
public class InvocationAdapterRegistry
{
private Dictionary<string, IInvocationAdapter> _invocationAdapters = new Dictionary<string, IInvocationAdapter>();
private readonly IServiceProvider _serviceProvider;
private readonly SignalROptions _options;
public void RegisterInvocationAdapter(string format, IInvocationAdapter adapter)
public InvocationAdapterRegistry(IOptions<SignalROptions> options, IServiceProvider serviceProvider)
{
_invocationAdapters[format] = adapter;
_options = options.Value;
_serviceProvider = serviceProvider;
}
public IInvocationAdapter GetInvocationAdapter(string format)
{
IInvocationAdapter value;
Type type;
if (_options._invocationMappings.TryGetValue(format, out type))
{
return _serviceProvider.GetRequiredService(type) as IInvocationAdapter;
}
return _invocationAdapters.TryGetValue(format, out value) ? value : null;
return null;
}
}
}

View File

@ -1,10 +1,9 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.SignalR;
using Newtonsoft.Json;
namespace ChatSample
namespace Microsoft.AspNetCore.SignalR
{
public class JsonNetInvocationAdapter : IInvocationAdapter
{
@ -17,6 +16,7 @@ namespace ChatSample
public async Task<InvocationDescriptor> ReadInvocationDescriptor(Stream stream, Func<string, Type[]> getParams)
{
var reader = new JsonTextReader(new StreamReader(stream));
// REVIEW: Task.Run()
return await Task.Run(() => _serializer.Deserialize<InvocationDescriptor>(reader));
}

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Microsoft.AspNetCore.SignalR
{
public class SignalROptions
{
internal readonly Dictionary<string, Type> _invocationMappings = new Dictionary<string, Type>();
public void RegisterInvocationAdapter<TInvocationAdapter>(string format) where TInvocationAdapter : IInvocationAdapter
{
_invocationMappings[format] = typeof(TInvocationAdapter);
}
}
}

View File

@ -0,0 +1,14 @@
using System;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.DependencyInjection
{
public class SignalROptionsSetup : IConfigureOptions<SignalROptions>
{
public void Configure(SignalROptions options)
{
options.RegisterInvocationAdapter<JsonNetInvocationAdapter>("json");
}
}
}

View File

@ -2,6 +2,7 @@
"version": "1.0.0-*",
"dependencies": {
"Newtonsoft.Json": "9.0.1",
"Microsoft.AspNetCore.Sockets": {
"target": "project"
}