Remove one-way WCF service and replace with SignalR methods

This commit is contained in:
2015-01-17 08:06:12 -05:00
parent f4f1c3c784
commit 7608922bd7
11 changed files with 116 additions and 160 deletions

View File

@@ -1,27 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="WeatherService.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<sectionGroup name="applicationSettings"
type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="WeatherService.Settings"
type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</sectionGroup>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
requirePermission="false" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
<supportedRuntime version="v4.0"
sku=".NETFramework,Version=v4.5" />
</startup>
<applicationSettings>
<WeatherService.Settings>
<setting name="LogDatabase" serializeAs="String">
<setting name="LogDatabase"
serializeAs="String">
<value>False</value>
</setting>
<setting name="PollingInterval" serializeAs="String">
<setting name="PollingInterval"
serializeAs="String">
<value>00:00:01</value>
</setting>
<setting name="SignalR_ListenUrl" serializeAs="String">
<setting name="SignalR_ListenUrl"
serializeAs="String">
<value>http://*:9090</value>
</setting>
<setting name="SignalR_ConnectUrl" serializeAs="String">
<setting name="SignalR_ConnectUrl"
serializeAs="String">
<value>http://localhost:9090</value>
</setting>
</WeatherService.Settings>
@@ -29,7 +39,8 @@
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webHttpBindingWithJson" crossDomainScriptAccessEnabled="true" />
<binding name="webHttpBindingWithJson"
crossDomainScriptAccessEnabled="true" />
</webHttpBinding>
<netTcpBinding>
<binding name="netTcpBindingNoSecurity">
@@ -38,23 +49,21 @@
</netTcpBinding>
</bindings>
<services>
<service behaviorConfiguration="Default" name="WeatherService.WeatherServiceDuplex">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="netTcpBindingNoSecurity" contract="WeatherService.IWeatherServiceDuplex" />
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<service behaviorConfiguration="Default"
name="WeatherService.Remote.WeatherServiceDuplex">
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration="netTcpBindingNoSecurity"
contract="WeatherService.Remote.IWeatherServiceDuplex" />
<endpoint address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://server:9001" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="Default" name="WeatherService.WeatherService">
<endpoint address="json" binding="webHttpBinding" bindingConfiguration="webHttpBindingWithJson" contract="WeatherService.IWeatherService" />
<host>
<baseAddresses>
<add baseAddress="http://server:9000" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
@@ -67,24 +76,39 @@
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.AspNet.SignalR.Core" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0" newVersion="2.2.0.0" />
<assemblyIdentity name="Microsoft.AspNet.SignalR.Core"
publicKeyToken="31bf3856ad364e35"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.2.0.0"
newVersion="2.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
<assemblyIdentity name="Microsoft.Owin"
publicKeyToken="31bf3856ad364e35"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0"
newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
<assemblyIdentity name="Newtonsoft.Json"
publicKeyToken="30ad4fe6b2a6aeed"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0"
newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
<assemblyIdentity name="Microsoft.Owin.Security"
publicKeyToken="31bf3856ad364e35"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0"
newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Cors" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.2.0" newVersion="5.2.2.0" />
<assemblyIdentity name="System.Web.Cors"
publicKeyToken="31bf3856ad364e35"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.2.0"
newVersion="5.2.2.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
@@ -95,11 +119,16 @@
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="System.Data.SqlClient"
type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework>
<connectionStrings>
<add name="WeatherData" connectionString="data source=localhost\Weather;initial catalog=Weather;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
<add name="WeatherArchiveData" connectionString="data source=localhost\Weather;initial catalog=WeatherDataTest;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
<add name="WeatherData"
connectionString="data source=localhost\Weather;initial catalog=Weather;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"
providerName="System.Data.SqlClient" />
<add name="WeatherArchiveData"
connectionString="data source=localhost\Weather;initial catalog=WeatherDataTest;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>

View File

@@ -1,31 +0,0 @@
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Web;
using WeatherService.Devices;
using WeatherService.Remote;
using WeatherService.Values;
namespace WeatherService
{
[ServiceContract]
public interface IWeatherService
{
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
List<DeviceBase> GetDevices();
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType);
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
DeviceHistory GetDeviceHistory(string deviceAddress);
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
Dictionary<DeviceBase, List<ReadingBase>> GetDeviceHistoryByValueType(WeatherValueType valueType);
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes);
[WebGet(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
Dictionary<string, int> GetWindDirectionHistory();
}
}

View File

@@ -1,9 +1,9 @@
using System.ServiceModel;
using WeatherService.Devices;
namespace WeatherService
namespace WeatherService.Remote
{
public interface IWeatherServiceCallback
public interface IWeatherServiceCallback : ICommunicationObject
{
[OperationContract(IsOneWay = true)]
void OnDeviceUpdate(DeviceBase device);

View File

@@ -1,10 +1,9 @@
using System.Collections.Generic;
using System.ServiceModel;
using WeatherService.Devices;
using WeatherService.Remote;
using WeatherService.Values;
namespace WeatherService
namespace WeatherService.Remote
{
[ServiceContract(CallbackContract = typeof(IWeatherServiceCallback))]
public interface IWeatherServiceDuplex

View File

@@ -1,55 +0,0 @@
using System.Collections.Generic;
using System.ServiceModel.Activation;
using System.ServiceModel.Web;
using WeatherService.Devices;
using WeatherService.Remote;
using WeatherService.Values;
namespace WeatherService
{
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class WeatherService : IWeatherService
{
public List<DeviceBase> GetDevices()
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
return WeatherServiceCommon.GetDevices();
}
public ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType)
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
return WeatherServiceCommon.GetLatestReading(deviceAddress, valueType);
}
public DeviceHistory GetDeviceHistory(string deviceAddress)
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
return WeatherServiceCommon.GetDeviceHistory(deviceAddress);
}
public Dictionary<DeviceBase, List<ReadingBase>> GetDeviceHistoryByValueType(WeatherValueType valueType)
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
return WeatherServiceCommon.GetDeviceHistoryByValueType(valueType);
}
public Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes)
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
return WeatherServiceCommon.GetWindSpeedHistory(groupIntervalMinutes);
}
public Dictionary<string, int> GetWindDirectionHistory()
{
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
return WeatherServiceCommon.GetWindDirectionHistory();
}
}
}

View File

@@ -17,7 +17,7 @@ namespace WeatherService.Remote
public static ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType)
{
DeviceBase deviceBase = Program.Session.Devices.Where(d => d.Address == deviceAddress).FirstOrDefault();
var deviceBase = Program.Session.Devices.FirstOrDefault(d => d.Address == deviceAddress);
if (deviceBase == null)
return null;
@@ -27,12 +27,12 @@ namespace WeatherService.Remote
public static DeviceHistory GetDeviceHistory(string deviceAddress)
{
DeviceBase deviceBase = Program.Session.Devices.Where(d => d.Address == deviceAddress).FirstOrDefault();
var deviceBase = Program.Session.Devices.FirstOrDefault(d => d.Address == deviceAddress);
if (deviceBase == null)
return null;
DeviceHistory deviceHistory = new DeviceHistory();
var deviceHistory = new DeviceHistory();
foreach (var valueEntry in deviceBase.Values)
{
@@ -46,7 +46,7 @@ namespace WeatherService.Remote
{
var devices = Program.Session.Devices.Where(d => d.SupportedValues.Contains(valueType));
Dictionary<DeviceBase, List<ReadingBase>> deviceHistoryList = new Dictionary<DeviceBase, List<ReadingBase>>();
var deviceHistoryList = new Dictionary<DeviceBase, List<ReadingBase>>();
foreach (var device in devices)
{
@@ -60,20 +60,20 @@ namespace WeatherService.Remote
{
var windSpeedHistory = new Dictionary<string, List<WindSpeedReading>>();
var device = Program.Session.Devices.Where(d => d.SupportedValues.Contains(WeatherValueType.WindSpeed)).FirstOrDefault();
var device = Program.Session.Devices.FirstOrDefault(d => d.SupportedValues.Contains(WeatherValueType.WindSpeed));
if (device == null)
return null;
var values = device.GetValue(WeatherValueType.WindSpeed).History;
TimeSpan interval = new TimeSpan(0, groupIntervalMinutes, 0);
var interval = new TimeSpan(0, groupIntervalMinutes, 0);
var groupList = values.GroupBy(reading => reading.ReadTime.Ticks / interval.Ticks).Select(d => new
{
ReadTime = new DateTime(d.Key * interval.Ticks),
Readings = d.Select(r => r.Value)
});
}).ToList();
windSpeedHistory["Average"] = groupList.Select(d => new WindSpeedReading(WeatherValueType.WindSpeed) { ReadTime = d.ReadTime, Value = d.Readings.Average() }).ToList();
windSpeedHistory["Minimum"] = groupList.Select(d => new WindSpeedReading(WeatherValueType.WindSpeed) { ReadTime = d.ReadTime, Value = d.Readings.Min() }).ToList();
@@ -84,7 +84,7 @@ namespace WeatherService.Remote
public static Dictionary<string, int> GetWindDirectionHistory()
{
var device = Program.Session.Devices.Where(d => d.SupportedValues.Contains(WeatherValueType.WindDirection)).FirstOrDefault();
var device = Program.Session.Devices.FirstOrDefault(d => d.SupportedValues.Contains(WeatherValueType.WindDirection));
if (device == null)
return null;

View File

@@ -1,15 +1,14 @@
using System.Collections.Generic;
using System.ServiceModel;
using WeatherService.Devices;
using WeatherService.Remote;
using WeatherService.Values;
namespace WeatherService
namespace WeatherService.Remote
{
[CallbackBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class WeatherServiceDuplex : IWeatherServiceDuplex
{
private static readonly List<IWeatherServiceCallback> subscribers = new List<IWeatherServiceCallback>();
private static readonly List<IWeatherServiceCallback> Subscribers = new List<IWeatherServiceCallback>();
public List<DeviceBase> GetDevices()
{
@@ -45,10 +44,10 @@ namespace WeatherService
{
try
{
IWeatherServiceCallback callback = OperationContext.Current.GetCallbackChannel<IWeatherServiceCallback>();
var callback = OperationContext.Current.GetCallbackChannel<IWeatherServiceCallback>();
if (!subscribers.Contains(callback))
subscribers.Add(callback);
if (!Subscribers.Contains(callback))
Subscribers.Add(callback);
return true;
}
@@ -62,10 +61,10 @@ namespace WeatherService
{
try
{
IWeatherServiceCallback callback = OperationContext.Current.GetCallbackChannel<IWeatherServiceCallback>();
var callback = OperationContext.Current.GetCallbackChannel<IWeatherServiceCallback>();
if (subscribers.Contains(callback))
subscribers.Remove(callback);
if (Subscribers.Contains(callback))
Subscribers.Remove(callback);
return true;
}
@@ -81,7 +80,7 @@ namespace WeatherService
var removeList = new List<IWeatherServiceCallback>();
// Loop over each subscriber
foreach (var callback in subscribers)
foreach (var callback in Subscribers)
{
// If the callback connection isn't open...
if ((callback as ICommunicationObject).State != CommunicationState.Opened)
@@ -105,7 +104,7 @@ namespace WeatherService
}
// Remove all callbacks in the remove list
removeList.ForEach(o => subscribers.Remove(o));
removeList.ForEach(o => Subscribers.Remove(o));
}
}
}

View File

@@ -1,11 +1,11 @@
using Common.Debug;
using Microsoft.Owin.Hosting;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.ServiceModel.Web;
using System.ServiceProcess;
using WeatherService.Framework;
using WeatherService.Remote;
using WeatherService.SignalR;
namespace WeatherService
@@ -13,7 +13,7 @@ namespace WeatherService
[WindowsService("WeatherReporting", DisplayName = "Weather Reporting", Description = "", StartMode = ServiceStartMode.Automatic, ServiceAccount = ServiceAccount.LocalSystem)]
public class ServiceImplementation : IWindowsService
{
private List<WebServiceHost> _serviceHosts;
private WebServiceHost _serviceHost;
private IDisposable _signalR;
public void OnStart(string[] args)
@@ -22,13 +22,8 @@ namespace WeatherService
{
try
{
_serviceHosts = new List<WebServiceHost>
{
new WebServiceHost(typeof (WeatherService)),
new WebServiceHost(typeof (WeatherServiceDuplex))
};
_serviceHosts.ForEach(h => h.Open());
_serviceHost = new WebServiceHost(typeof(WeatherServiceDuplex));
_serviceHost.Open();
_signalR = WebApp.Start<Startup>(Settings.Default.SignalR_ListenUrl);
Trace.Listeners.Remove("HostingTraceListener");
@@ -57,8 +52,7 @@ namespace WeatherService
_signalR.Dispose();
_serviceHosts.ForEach(h => h.Close());
_serviceHosts.Clear();
_serviceHost.Close();
}
catch (Exception exception)
{

View File

@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading;
using WeatherService.Devices;
using WeatherService.Remote;
using WeatherService.SignalR;
namespace WeatherService

View File

@@ -1,7 +1,8 @@
using System.Collections.Generic;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR;
using System.Collections.Generic;
using WeatherService.Devices;
using WeatherService.Remote;
using WeatherService.Values;
namespace WeatherService.SignalR
{
@@ -9,11 +10,32 @@ namespace WeatherService.SignalR
{
public List<DeviceBase> GetDevices()
{
var devices = WeatherServiceCommon.GetDevices();
return WeatherServiceCommon.GetDevices();
}
//var json = JsonConvert.SerializeObject(devices);
public ReadingBase GetLatestReading(string deviceAddress, WeatherValueType valueType)
{
return WeatherServiceCommon.GetLatestReading(deviceAddress, valueType);
}
return devices;
public DeviceHistory GetDeviceHistory(string deviceAddress)
{
return WeatherServiceCommon.GetDeviceHistory(deviceAddress);
}
public Dictionary<DeviceBase, List<ReadingBase>> GetDeviceHistoryByValueType(WeatherValueType valueType)
{
return WeatherServiceCommon.GetDeviceHistoryByValueType(valueType);
}
public Dictionary<string, List<WindSpeedReading>> GetWindSpeedHistory(int groupIntervalMinutes)
{
return WeatherServiceCommon.GetWindSpeedHistory(groupIntervalMinutes);
}
public Dictionary<string, int> GetWindDirectionHistory()
{
return WeatherServiceCommon.GetWindDirectionHistory();
}
}
}

View File

@@ -151,12 +151,10 @@
<DependentUpon>WindowsServiceInstaller.cs</DependentUpon>
</Compile>
<Compile Include="Remote\DeviceHistory.cs" />
<Compile Include="Remote\IWeatherService.cs" />
<Compile Include="Remote\IWeatherServiceDuplex.cs" />
<Compile Include="Remote\IWeatherServiceCallback.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Remote\WeatherService.cs" />
<Compile Include="Remote\WeatherServiceCommon.cs" />
<Compile Include="Remote\WeatherServiceDuplex.cs" />
<Compile Include="ServiceImplementation.cs" />