FAQ | This is a LIVE service | Changelog

Skip to content
Snippets Groups Projects
Commit e9cf4bd6 authored by Dr Adam Thorn's avatar Dr Adam Thorn
Browse files

Merge branch 'refactor_messaging'

parents 9e9e8a52 886faae8
No related branches found
No related tags found
No related merge requests found
using System.ServiceModel;
namespace WpkgInstaller
{
public delegate WpkgMessageRequestType WpkgEventCallbackHandler(object sender, WpkgMessageRequest e);
[ServiceContract(Namespace = "https://www.ch.cam.ac.uk/WpkgNotifier",
SessionMode = SessionMode.Required,
CallbackContract = typeof(IWpkgMessageCallbackHandlerContract))]
public interface IWpkgMessageRequestHandlerContract
{
[OperationContract(IsOneWay = true)]
void HandleMessage(WpkgMessageRequestType type);
}
}
......@@ -2,12 +2,12 @@
namespace WpkgInstaller
{
public interface IWpkgMessageCallbackHandlerContract
public interface IWpkgNotifierMessageClient
{
[OperationContract(IsOneWay = true)]
void HandleResponse(WpkgMessageResponse response);
void StatusLine(string msg);
[OperationContract(IsOneWay = true)]
void HandleMessage(WpkgMessageState status);
void SetStatus(WpkgMessageState status);
}
}
}
\ No newline at end of file
using System.ServiceModel;
namespace WpkgInstaller
{
[ServiceContract(CallbackContract = typeof(IWpkgNotifierMessageClient))]
public interface IWpkgNotifierMessageServer
{
[OperationContract(IsOneWay = true)]
void Register(int pid);
[OperationContract(IsOneWay = true)]
void Unregister(int pid);
[OperationContract(IsOneWay = true)]
void ProcessRequest(WpkgMessageRequestType type);
}
}
......@@ -3,6 +3,8 @@ using System.ServiceProcess;
using System.Diagnostics;
using System;
using System.ServiceModel;
using System.Collections;
using System.Collections.Generic;
namespace WpkgInstaller
{
......@@ -28,18 +30,21 @@ namespace WpkgInstaller
public int dwCheckPoint;
public int dwWaitHint;
};
public partial class WpkgInstaller : ServiceBase
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public partial class WpkgInstaller : ServiceBase, IWpkgNotifierMessageServer
{
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool SetServiceStatus(System.IntPtr handle, ref ServiceStatus serviceStatus);
private Dictionary<int, IWpkgNotifierMessageClient> clients;
private IWpkgMessageCallbackHandlerContract notifierCallbackHandler;
public WpkgInstaller()
{
InitializeComponent();
eventLog = new EventLog();
clients = new Dictionary<int, IWpkgNotifierMessageClient>();
string eventSourceName = "WpkgInstaller Service";
string logName = "WpkgNotifier";
......@@ -88,14 +93,12 @@ namespace WpkgInstaller
private void RunWpkgSync()
{
notifierCallbackHandler.HandleMessage(WpkgMessageState.SYNCING);
eventLog.WriteEntry("Starting sync", EventLogEntryType.Information);
RunWpkgCommand("/synchronize");
}
private void RunWpkgQuery()
{
notifierCallbackHandler.HandleMessage(WpkgMessageState.QUERYING);
eventLog.WriteEntry("Starting query", EventLogEntryType.Information);
RunWpkgCommand("/query:m");
}
......@@ -127,15 +130,13 @@ namespace WpkgInstaller
process.BeginOutputReadLine();
process.WaitForExit();
notifierCallbackHandler.HandleMessage(WpkgMessageState.IDLE);
if(process.ExitCode == 0)
{
notifierCallbackHandler.HandleMessage(WpkgMessageState.SUCCESS);
SetClientsState(WpkgMessageState.SUCCESS);
}
else
{
notifierCallbackHandler.HandleMessage(WpkgMessageState.ERROR);
SetClientsState(WpkgMessageState.ERROR);
}
String msg = String.Format("wpkg command finished, with exit code {0}", process.ExitCode);
eventLog.WriteEntry(msg, EventLogEntryType.Information);
......@@ -146,8 +147,7 @@ namespace WpkgInstaller
{
if (e != null && e.Data != null)
{
notifierCallbackHandler.HandleResponse(new WpkgMessageResponse(e.Data));
//eventLog.WriteEntry(e.Data, EventLogEntryType.Information);
// sent e.Data back to clients
}
}
......@@ -170,44 +170,83 @@ namespace WpkgInstaller
{
try
{
Uri BaseAddress = new Uri("net.pipe://localhost/www.ch.cam.ac.uk/WpkgNotifier");
Uri uri = new Uri("net.pipe://localhost/www.ch.cam.ac.uk/WpkgNotifier");
NetNamedPipeBinding binding = new NetNamedPipeBinding();
ServiceHost serviceHost = new ServiceHost(this, uri);
serviceHost.AddServiceEndpoint(typeof(IWpkgNotifierMessageServer), binding, "");
serviceHost.Open();
WpkgInstallerMessageService svc = new WpkgInstallerMessageService();
ServiceHost SvcHost = new ServiceHost(svc, BaseAddress);
SvcHost.AddServiceEndpoint(typeof(IWpkgMessageRequestHandlerContract), binding, "");
SvcHost.Open();
eventLog.WriteEntry("serviceHost now open");
(SvcHost.SingletonInstance as WpkgInstallerMessageService).WpkgEventCallback += new WpkgEventCallbackHandler(ProcessMessage);
}
catch (Exception e)
{
eventLog.WriteEntry(e.Message);
eventLog.WriteEntry(e.Message, EventLogEntryType.Error);
throw e;
}
}
private WpkgMessageRequestType ProcessMessage(object sender, WpkgMessageRequest e)
public void Register(int pid)
{
if (notifierCallbackHandler == null)
eventLog.WriteEntry(String.Format("Register requested for {0}", pid));
IWpkgNotifierMessageClient client = OperationContext.Current.GetCallbackChannel <IWpkgNotifierMessageClient>();
clients.Add(pid, client);
foreach(KeyValuePair<int, IWpkgNotifierMessageClient> kv in clients)
{
notifierCallbackHandler = OperationContext.Current.GetCallbackChannel<IWpkgMessageCallbackHandlerContract>();
try
{
kv.Value.StatusLine(String.Format("Register requested for {0}", pid));
}
catch (Exception e)
{
eventLog.WriteEntry("Error communicating with client " + kv.Key + " " + e.ToString(), EventLogEntryType.Warning);
}
}
}
eventLog.WriteEntry(string.Format("Got {0}", e.Type));
switch(e.Type)
public void Unregister(int pid)
{
if(clients.Remove(pid))
{
eventLog.WriteEntry(String.Format("Client {0} unregistered", pid));
}
else
{
eventLog.WriteEntry(String.Format("Unknown client {0} requested to unregister", pid), EventLogEntryType.Warning);
}
}
public void ProcessRequest(WpkgMessageRequestType type)
{
switch (type)
{
case WpkgMessageRequestType.DO_SYNC:
SetClientsState(WpkgMessageState.SYNCING);
RunWpkgSync();
break;
case WpkgMessageRequestType.RUN_QUERY:
SetClientsState(WpkgMessageState.QUERYING);
RunWpkgQuery();
break;
}
return WpkgMessageRequestType.DONE;
}
private void SetClientsState(WpkgMessageState state)
{
foreach (KeyValuePair<int, IWpkgNotifierMessageClient> kv in clients)
{
try
{
kv.Value.SetStatus(state);
}
catch (Exception e)
{
eventLog.WriteEntry("Error communicating with client " + kv.Key + " " + e.ToString(), EventLogEntryType.Warning);
}
}
}
}
}
......@@ -70,7 +70,8 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="IWpkgMessageCallbackHandlerContract.cs" />
<Compile Include="IWpkgNotifierMessageClient.cs" />
<Compile Include="IWpkgNotifierMessageServer.cs" />
<Compile Include="ProjectInstaller.cs">
<SubType>Component</SubType>
</Compile>
......@@ -85,8 +86,6 @@
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="WpkgInstallerMessageService.cs" />
<Compile Include="IWpkgMessageRequestHandlerContract.cs" />
<Compile Include="WpkgMessageRequest.cs" />
<Compile Include="WpkgMessageResponse.cs" />
<Compile Include="WpkgMessageState.cs" />
......
using System.ServiceModel;
namespace WpkgInstaller
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class WpkgInstallerMessageService : IWpkgMessageRequestHandlerContract
{
public event WpkgEventCallbackHandler WpkgEventCallback = delegate { return WpkgMessageRequestType.DONE; };
public void HandleMessage(WpkgMessageRequestType type)
{
WpkgEventCallback(this, new WpkgMessageRequest(type));
}
}
}
......@@ -8,16 +8,20 @@ using WpkgInstaller;
namespace WpkgNotifier
{
class TrayNotifier : ApplicationContext, IWpkgMessageCallbackHandlerContract
class TrayNotifier : ApplicationContext, IWpkgNotifierMessageClient
{
private NotifyIcon notifyIcon;
private IWpkgMessageRequestHandlerContract messageChannel;
private EventLog eventLog;
private WpkgMessageState state;
private IWpkgNotifierMessageServer server;
private int pid;
public TrayNotifier()
{
Process currentProcess = Process.GetCurrentProcess();
pid = currentProcess.Id;
eventLog = new EventLog();
string eventSourceName = "TrayNotifier";
string logName = "WpkgNotifier";
......@@ -33,6 +37,8 @@ namespace WpkgNotifier
OpenMessageChannel();
Application.ApplicationExit += new EventHandler(this.OnApplicationExit);
MenuItem actionsMenu = new MenuItem("Actions");
MenuItem syncMenuItem = new MenuItem("Sync", new EventHandler(RequestSync));
MenuItem queryMenuItem = new MenuItem("Query", new EventHandler(RequestQuery));
......@@ -64,24 +70,30 @@ namespace WpkgNotifier
};
}
private void OnApplicationExit(object sender, EventArgs e)
{
server.Unregister(pid);
}
private void OpenMessageChannel()
{
eventLog.WriteEntry("Trying to open channel");
try
{
string address = "net.pipe://localhost/www.ch.cam.ac.uk/WpkgNotifier";
NetNamedPipeBinding binding = new NetNamedPipeBinding();
string uri = "net.pipe://localhost/www.ch.cam.ac.uk/WpkgNotifier";
InstanceContext context = new InstanceContext(this);
DuplexChannelFactory<IWpkgMessageRequestHandlerContract> factory = new DuplexChannelFactory<IWpkgMessageRequestHandlerContract>(context, binding, address);
DuplexChannelFactory<IWpkgNotifierMessageServer> channelFactory =
new DuplexChannelFactory<IWpkgNotifierMessageServer>(context, binding, uri);
messageChannel = factory.CreateChannel();
server = channelFactory.CreateChannel();
eventLog.WriteEntry("channel created");
server.Register(pid);
eventLog.WriteEntry("Registered with server");
}
catch (Exception e)
{
eventLog.WriteEntry("problem creating channel");
eventLog.WriteEntry(e.Message);
}
}
......@@ -89,13 +101,13 @@ namespace WpkgNotifier
void RequestSync(object sender, EventArgs e)
{
notifyIcon.ContextMenu.MenuItems[0].Enabled = false;
messageChannel.HandleMessage(WpkgMessageRequestType.DO_SYNC);
server.ProcessRequest(WpkgMessageRequestType.DO_SYNC);
}
void RequestQuery(object sender, EventArgs e)
{
notifyIcon.ContextMenu.MenuItems[0].Enabled = false;
messageChannel.HandleMessage(WpkgMessageRequestType.RUN_QUERY);
server.ProcessRequest(WpkgMessageRequestType.RUN_QUERY);
}
void ManageSoftware(object sender, EventArgs e)
......@@ -111,6 +123,8 @@ namespace WpkgNotifier
Application.Exit();
}
public void SetToolTip(string msg)
{
notifyIcon.Text = msg;
......@@ -121,7 +135,7 @@ namespace WpkgNotifier
eventLog.WriteEntry(response.Message);
}
public void HandleMessage(WpkgMessageState status)
public void SetStatus(WpkgMessageState status)
{
this.state = status;
switch (status)
......@@ -145,5 +159,10 @@ namespace WpkgNotifier
break;
}
}
public void StatusLine(string msg)
{
SetToolTip(msg);
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment