interface IMessageCallback { [OperationContract(IsOneWay = true)] void OnMessageAdded(int senderId, string message, DateTime timestamp); }
[ServiceContract(CallbackContract = typeof(IMessageCallback))] public interface IMessageService { [OperationContract] void AddMessage(int senderId, int recipientId, string message); [OperationContract] bool Subscribe(); }
Public class MessageService : IMessageService { private static List<IMessageCallback> subscribers = new List<IMessageCallback>(); public bool Subscribe(int id) { try { IMessageCallback callback = OperationContext.Current.GetCallbackChannel<IMessageCallback>(); callback.id = id; if (!subscribers.Contains(callback)) subscribers.Add(callback); return true; } catch { return false; } } public void AddMessage(int senderId, int recipientId, string message) { subscribers.ForEach(delegate(IMessageCallback callback) { if ((((ICommunicationObject)callback).State == CommunicationState.Opened) && (callback.id == recipientId)) { callback.OnMessageAdded(recipientId, message, DateTime.Now); } else { subscribers.Remove(callback); } }); } }
<system.serviceModel> <services> <service name="WCFPush.MessageService" behaviorConfiguration="Default"> <endpoint address ="" binding="wsDualHttpBinding" contract="WCFPush.IMessage"> </endpoint> </service> </services> <behaviors> <serviceBehaviors> <behavior name="Default"> <serviceMetadata httpGetEnabled="True"/> <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
[ServiceContract] public interface IMessageService { [WebGet(UriTemplate = "AddMessage?senderId={senderId}&recipientId={recipientId}&message={message}")] [OperationContract ] bool AddMessage(int senderId, int recipientId, string message); [WebGet(UriTemplate = "Subscribe?id={id}")] [OperationContract(AsyncPattern = true)] IAsyncResult BeginGetMessage(int id, AsyncCallback callback, object asyncState); ServiceMessage EndGetMessage(IAsyncResult result); }
public class MessageAsyncResult : IAsyncResult { public AsyncCallback Callback { get; set; } private readonly object accessLock = new object(); private bool isCompleted = false; private ServiceMessage result; private int recipientId; private object asyncState; public MessageAsyncResult(object state) { asyncState = state; } public int RecipientId { get { lock (accessLock) { return recipientId; } } set { lock (accessLock) { recipientId = value; } } } public ServiceMessage Result { get { lock (accessLock) { return result; } } set { lock (accessLock) { result = value; } } } public bool IsCompleted { get { lock (accessLock) { return isCompleted; } } set { lock (accessLock) { isCompleted = value; } } } public bool CompletedSynchronously { get { return false; } } public object AsyncState { get { return asyncState; } } public WaitHandle AsyncWaitHandle { get { return null; } } }
[ServiceBehavior( InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)] public class MessageService : IMessageService { private static List<MessageAsyncResult> subscribers = new List<MessageAsyncResult>(); public bool AddMessage(int senderId, int recipientId, string message) { subscribers.ForEach(delegate(MessageAsyncResult result) { if (result.RecipientId == recipientId) { result.Result = new ServiceMessage(senderId, recipientId, message, DateTime.Now); result.IsCompleted = true; result.Callback(result); subscribers.Remove(result); } }); return true; } public IAsyncResult BeginGetMessage(int id, AsyncCallback callback, object asyncState) { MessageAsyncResult asyncResult = new MessageAsyncResult(asyncState); asyncResult.Callback = callback; asyncResult.RecipientId = id; subscribers.Add(asyncResult); return asyncResult; } public ServiceMessage EndGetMessage(IAsyncResult result) { return (result as MessageAsyncResult).Result; } }
<system.serviceModel> <bindings> <webHttpBinding> <binding name="webBinding"> </binding> </webHttpBinding> </bindings> <services> <service name=" WCFPush.MessageService" behaviorConfiguration="Default"> <endpoint address="" contract="WCFPush.IMessageService" behaviorConfiguration="web" bindingConfiguration="webBinding" binding="webHttpBinding"> </endpoint> </service> </services> <behaviors> <endpointBehaviors> <behavior name="web"> <webHttp /> </behavior> </endpointBehaviors> <serviceBehaviors> <behavior name="Default"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="false" /> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment multipleSiteBindingsEnabled="true" /> </system.serviceModel>
Source: https://habr.com/ru/post/128634/
All Articles