Skip to content

Commit d13f75e

Browse files
committed
Add support for web service protocol
1 parent c92bcb3 commit d13f75e

File tree

11 files changed

+350
-1
lines changed

11 files changed

+350
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Surging.Core.Protocol.WebService.Runtime
8+
{
9+
public interface IWebServiceEntryProvider
10+
{
11+
IEnumerable<WebServiceEntry> GetEntries();
12+
13+
List<WebServiceEntry> CreateServiceEntries(Type service);
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using Microsoft.Extensions.Logging;
2+
using Surging.Core.CPlatform;
3+
using Surging.Core.CPlatform.Routing.Template;
4+
using Surging.Core.CPlatform.Runtime.Server;
5+
using Surging.Core.CPlatform.Runtime.Server.Implementation.ServiceDiscovery.Attributes;
6+
using System;
7+
using System.Collections.Generic;
8+
using System.Linq;
9+
using System.Reflection;
10+
using System.Text;
11+
using System.Threading.Tasks;
12+
13+
namespace Surging.Core.Protocol.WebService.Runtime.Implementation
14+
{
15+
public class DefaultWebServiceEntryProvider : IWebServiceEntryProvider
16+
{
17+
#region Field
18+
private readonly IServiceEntryProvider _serviceEntryProvider;
19+
private readonly IEnumerable<Type> _types;
20+
private readonly ILogger<DefaultWebServiceEntryProvider> _logger;
21+
private readonly CPlatformContainer _serviceProvider;
22+
private List<WebServiceEntry> _webServiceEntries;
23+
24+
#endregion Field
25+
26+
#region Constructor
27+
28+
public DefaultWebServiceEntryProvider(IServiceEntryProvider serviceEntryProvider,
29+
ILogger<DefaultWebServiceEntryProvider> logger,
30+
CPlatformContainer serviceProvider)
31+
{
32+
_types = serviceEntryProvider.GetTypes();
33+
_serviceEntryProvider = serviceEntryProvider;
34+
_logger = logger;
35+
_serviceProvider = serviceProvider;
36+
}
37+
38+
#endregion Constructor
39+
40+
#region Implementation of IServiceEntryProvider
41+
42+
/// <summary>
43+
/// 获取服务条目集合。
44+
/// </summary>
45+
/// <returns>服务条目集合。</returns>
46+
public IEnumerable<WebServiceEntry> GetEntries()
47+
{
48+
var services = _types.ToArray();
49+
if (_webServiceEntries == null)
50+
{
51+
_webServiceEntries = new List<WebServiceEntry>();
52+
foreach (var service in services)
53+
{
54+
var entries = CreateServiceEntries(service);
55+
if (entries != null)
56+
{
57+
_webServiceEntries.AddRange(entries);
58+
}
59+
}
60+
if (_logger.IsEnabled(LogLevel.Debug))
61+
{
62+
_logger.LogDebug($"发现了以下WebService服务:{string.Join(",", _webServiceEntries.Select(i => i.Type.FullName))}。");
63+
}
64+
}
65+
return _webServiceEntries;
66+
}
67+
#endregion
68+
69+
70+
public List<WebServiceEntry> CreateServiceEntries(Type service)
71+
{
72+
List<WebServiceEntry> result = new List<WebServiceEntry>();
73+
var routeTemplate = service.GetCustomAttribute<ServiceBundleAttribute>();
74+
var objInstance = _serviceProvider.GetInstances(service);
75+
var behavior = objInstance as WebServiceBehavior;
76+
var path = RoutePatternParser.Parse(routeTemplate?.RouteTemplate, service.Name);
77+
if (path.Length > 0 && path[0] != '/')
78+
path = $"/{path}";
79+
if (behavior != null)
80+
{
81+
var entries = _serviceEntryProvider.GetALLEntries().Where(p => p.Type == service).ToList();
82+
foreach (var entry in entries)
83+
{
84+
result.Add(new WebServiceEntry
85+
{
86+
Behavior = behavior,
87+
BaseType = service,
88+
Type = behavior.GetType(),
89+
Path = entry.RoutePath,
90+
});
91+
}
92+
}
93+
return result;
94+
}
95+
}
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
using Autofac;
2+
using Surging.Core.CPlatform.EventBus.Events;
3+
using Surging.Core.CPlatform.EventBus.Implementation;
4+
using Surging.Core.CPlatform.Ioc;
5+
using Surging.Core.CPlatform.Messages;
6+
using Surging.Core.CPlatform.Utilities;
7+
using Surging.Core.ProxyGenerator;
8+
using System;
9+
using System.Collections.Generic;
10+
using System.Linq;
11+
using System.Text;
12+
using System.Threading.Tasks;
13+
14+
namespace Surging.Core.Protocol.WebService.Runtime
15+
{
16+
public abstract class WebServiceBehavior : IServiceBehavior
17+
{
18+
private ServerReceivedDelegate _received;
19+
public event ServerReceivedDelegate Received
20+
{
21+
add
22+
{
23+
24+
_received += value;
25+
}
26+
remove
27+
{
28+
_received -= value;
29+
}
30+
}
31+
32+
33+
34+
public string MessageId { get; } = Guid.NewGuid().ToString("N");
35+
36+
37+
public async Task Write(object result, int statusCode = 200, string exceptionMessage = "")
38+
{
39+
if (_received == null)
40+
return;
41+
var message = new TransportMessage(MessageId, new ReactiveResultMessage
42+
{
43+
ExceptionMessage = exceptionMessage,
44+
StatusCode = statusCode,
45+
Result = result
46+
47+
});
48+
await _received(message);
49+
}
50+
public T CreateProxy<T>(string key) where T : class
51+
{
52+
return ServiceLocator.GetService<IServiceProxyFactory>().CreateProxy<T>(key);
53+
}
54+
55+
public object CreateProxy(Type type)
56+
{
57+
return ServiceLocator.GetService<IServiceProxyFactory>().CreateProxy(type);
58+
}
59+
60+
public object CreateProxy(string key, Type type)
61+
{
62+
return ServiceLocator.GetService<IServiceProxyFactory>().CreateProxy(key, type);
63+
}
64+
65+
public T CreateProxy<T>() where T : class
66+
{
67+
return ServiceLocator.GetService<IServiceProxyFactory>().CreateProxy<T>();
68+
}
69+
70+
public T GetService<T>(string key) where T : class
71+
{
72+
if (ServiceLocator.Current.IsRegisteredWithKey<T>(key))
73+
return ServiceLocator.GetService<T>(key);
74+
else
75+
return ServiceLocator.GetService<IServiceProxyFactory>().CreateProxy<T>(key);
76+
}
77+
78+
public T GetService<T>() where T : class
79+
{
80+
if (ServiceLocator.Current.IsRegistered<T>())
81+
return ServiceLocator.GetService<T>();
82+
else
83+
return ServiceLocator.GetService<IServiceProxyFactory>().CreateProxy<T>();
84+
85+
}
86+
87+
public object GetService(Type type)
88+
{
89+
if (ServiceLocator.Current.IsRegistered(type))
90+
return ServiceLocator.GetService(type);
91+
else
92+
return ServiceLocator.GetService<IServiceProxyFactory>().CreateProxy(type);
93+
}
94+
95+
public object GetService(string key, Type type)
96+
{
97+
if (ServiceLocator.Current.IsRegisteredWithKey(key, type))
98+
return ServiceLocator.GetService(key, type);
99+
else
100+
return ServiceLocator.GetService<IServiceProxyFactory>().CreateProxy(key, type);
101+
102+
}
103+
104+
105+
public void Publish(IntegrationEvent @event)
106+
{
107+
GetService<IEventBus>().Publish(@event);
108+
}
109+
110+
}
111+
}
112+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace Surging.Core.Protocol.WebService.Runtime
8+
{
9+
public class WebServiceEntry
10+
{
11+
public string Path { get; set; }
12+
13+
public Type Type { get; set; }
14+
15+
public Type BaseType { get; set; }
16+
17+
public WebServiceBehavior Behavior { get; set; }
18+
}
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="SoapCore" Version="1.1.0.36" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<ProjectReference Include="..\Surging.Core.KestrelHttpServer\Surging.Core.KestrelHttpServer.csproj" />
15+
</ItemGroup>
16+
17+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using Autofac;
2+
using Microsoft.Extensions.Logging;
3+
using SoapCore;
4+
using Surging.Core.CPlatform;
5+
using Surging.Core.CPlatform.Module;
6+
using Surging.Core.CPlatform.Runtime.Server;
7+
using Surging.Core.KestrelHttpServer;
8+
using Surging.Core.Protocol.WebService.Runtime;
9+
using Surging.Core.Protocol.WebService.Runtime.Implementation;
10+
using System.ServiceModel;
11+
12+
namespace Surging.Core.Protocol.WebService
13+
{
14+
public class WebServiceModule : KestrelHttpModule
15+
{
16+
private IWebServiceEntryProvider _webServiceEntryProvider;
17+
public override void Initialize(AppModuleContext context)
18+
{
19+
_webServiceEntryProvider = context.ServiceProvoider.GetInstances<IWebServiceEntryProvider>();
20+
}
21+
22+
public override void Initialize(ApplicationInitializationContext builder)
23+
{
24+
var webServiceEntries = _webServiceEntryProvider.GetEntries();
25+
var binging = new BasicHttpBinding();
26+
binging.ReaderQuotas.MaxStringContentLength = int.MaxValue;
27+
foreach (var webServiceEntry in webServiceEntries)
28+
builder.Builder.UseSoapEndpoint(webServiceEntry.BaseType, $"/{webServiceEntry.Path}.asmx", new SoapEncoderOptions(), SoapSerializer.XmlSerializer);
29+
}
30+
31+
32+
public override void RegisterBuilder(ConfigurationContext context)
33+
{
34+
context.Services.AddSoapCore();
35+
}
36+
37+
protected async override void RegisterBuilder(ContainerBuilderWrapper builder)
38+
{
39+
builder.Register(provider =>
40+
{
41+
return new DefaultWebServiceEntryProvider(
42+
provider.Resolve<IServiceEntryProvider>(),
43+
provider.Resolve<ILogger<DefaultWebServiceEntryProvider>>(),
44+
provider.Resolve<CPlatformContainer>()
45+
);
46+
}).As(typeof(IWebServiceEntryProvider)).SingleInstance();
47+
}
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Surging.Core.CPlatform.Ioc;
2+
using Surging.Core.CPlatform.Runtime.Server.Implementation.ServiceDiscovery.Attributes;
3+
using System.ServiceModel;
4+
using System.Threading.Tasks;
5+
6+
namespace Surging.IModuleServices.Common
7+
{
8+
[ServiceBundle("api/{Service}/{Method}")]
9+
[ServiceContract]
10+
public interface IWebServiceService : IServiceKey
11+
{
12+
[OperationContract]
13+
Task<string> SayHello(string name);
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Surging.Core.Protocol.WebService.Runtime;
2+
using Surging.IModuleServices.Common;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
9+
namespace Surging.Modules.Common.Domain
10+
{
11+
public class WebServiceService : WebServiceBehavior, IWebServiceService
12+
{
13+
public Task<string> SayHello(string name)
14+
{
15+
return Task.FromResult($"Hello,{name}");
16+
}
17+
}
18+
}

src/Surging.Modules/Surging.Modules.Common/Surging.Modules.Common.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Protocol.Mqtt\Surging.Core.Protocol.Mqtt.csproj" />
2525
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Protocol.Tcp\Surging.Core.Protocol.Tcp.csproj" />
2626
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Protocol.Udp\Surging.Core.Protocol.Udp.csproj" />
27+
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Protocol.WebService\Surging.Core.Protocol.WebService.csproj" />
2728
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Protocol.WS\Surging.Core.Protocol.WS.csproj" />
2829
<ProjectReference Include="..\..\Surging.Core\Surging.Core.ServiceHosting.Extensions\Surging.Core.ServiceHosting.Extensions.csproj" />
2930
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Thrift\Surging.Core.Thrift.csproj" />

src/Surging.Services/Surging.Services.Server/Surging.Services.Server.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535

3636
<ItemGroup>
3737
<ProjectReference Include="..\..\Surging.Apm\Surging.Apm.Skywalking\Surging.Apm.Skywalking.csproj" />
38-
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Abp\Surging.Core.Abp.csproj" />
3938
<ProjectReference Include="..\..\Surging.Core\Surging.Core.ApiGateWay\Surging.Core.ApiGateWay.csproj" />
4039
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Caching\Surging.Core.Caching.csproj" />
4140
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Codec.MessagePack\Surging.Core.Codec.MessagePack.csproj" />
@@ -58,6 +57,7 @@
5857
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Protocol.Mqtt\Surging.Core.Protocol.Mqtt.csproj" />
5958
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Protocol.Tcp\Surging.Core.Protocol.Tcp.csproj" />
6059
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Protocol.Udp\Surging.Core.Protocol.Udp.csproj" />
60+
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Protocol.WebService\Surging.Core.Protocol.WebService.csproj" />
6161
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Protocol.WS\Surging.Core.Protocol.WS.csproj" />
6262
<ProjectReference Include="..\..\Surging.Core\Surging.Core.ProxyGenerator\Surging.Core.ProxyGenerator.csproj" />
6363
<ProjectReference Include="..\..\Surging.Core\Surging.Core.Serilog\Surging.Core.Serilog.csproj" />

0 commit comments

Comments
 (0)