WCF REST рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкреБрд╢ рд╕реВрдЪрдирд╛ рд╕реЗрд╡рд╛ рдХрд╛ рдирд┐рд░реНрдорд╛рдг

рдПрдХ рдкрд░рд┐рдЪрдп рдХреЗ рд░реВрдк рдореЗрдВ

рдкреБрд╢ рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди рдореЙрдбрд▓ рдПрдХ рдЖрдо рдореИрд╕реЗрдЬрд┐рдВрдЧ рдореЙрдбрд▓ рд╣реИред рдпрд╣ рдЕрдиреБрд░реЛрдз рдкрд░ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд░реНрд╡рд░ рдкрд░ рдпрд╣ рдЬрд╛рдирдХрд╛рд░реА рджрд┐рдЦрд╛рдИ рджреЗрдиреЗ рдкрд░ рддреБрд░рдВрдд рдкреНрд░реЗрд╖рдХ рдХреЛ рднреЗрдЬ рджреЗрддрд╛ рд╣реИред

WsDualHttpBinding рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдорд╛рдирдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг

WCF рджреНрд╡рд╛рд░рд╛ рдПрдХ рдкреБрд╢ рддрдВрддреНрд░ рдмрдирд╛рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рднреА рдкреНрд░рджрд╛рди рдХреА рдЬрд╛рддреА рд╣реИред рдпрд╣ рдврд╛рдВрдЪрд╛ рдЖрдкрдХреЛ wsDualHttpBinding рдЕрдиреБрдмрдВрдз рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдзрдХреНрдХрд╛ рд╕реЗрд╡рд╛ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдРрд╕рд╛ рдЕрдиреБрдмрдВрдз рдХреЙрд▓рдмреИрдХ рдкрджреНрдзрддрд┐ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдПрдХ рдШрдЯрдирд╛ рд╣реЛрдиреЗ рдкрд░ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдпрджрд┐ рд╣рдо рдЗрд╕ рддрдВрддреНрд░ рдХреЛ рдореИрд╕реЗрдЬрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдкрд░ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдорд┐рд▓рддреЗ рд╣реИрдВ:

- рдирдП рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП, рдПрдХ рдХреЙрд▓рдмреИрдХ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдирдП рд╕рдВрджреЗрд╢реЛрдВ рдХреЗ рд▓рд┐рдП рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реЛрддрд╛ рд╣реИред
- рдПрдХ рдирдпрд╛ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдиреЗ рдкрд░, рд╕рд┐рд╕реНрдЯрдо рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░реНрд╕ рдХреА рд╕реВрдЪреА рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ рдФрд░ рд╣рдореЗрдВ рдЙрд╕ рд╕рдВрджреЗрд╢ рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рдХреЛ рдвреВрдВрдврддрд╛ рд╣реИ рдЬрд┐рд╕рдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ (рдФрд░ рдЗрд╕рд▓рд┐рдП рд╡рд╛рдВрдЫрд┐рдд рдХреЙрд▓рдмреИрдХ)ред
- рд╣рдореЗрдВ рдЬрд┐рд╕ рдХреЙрд▓рдмреИрдХ рд╡рд┐рдзрд┐ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЙрд╕реЗ рд╣рдо рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд WCF рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП wsDualHttpBinding рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ:

- рдирдП рд╕рдВрджреЗрд╢реЛрдВ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓рдмреИрдХ рд╡рд┐рдзрд┐ рдмрдирд╛рдПрдВ
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); } }); } } 

- web.config рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕реЗрд╡рд╛ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░реЗрдВ
 <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> 

рд╕реЗрд╡рд╛ рддреИрдпрд╛рд░ рд╣реИред

рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрд╣ рдореЙрдбрд▓ рддрднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ рдЬрдм рд╕рд░реНрд╡рд░ рдФрд░ рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдмрд░ рджреЛрдиреЛрдВ .NET рдПрдкреНрд▓реАрдХреЗрд╢рди рд╣реЛрдВред

рдПрдХ рдИрдорд╛рдирджрд╛рд░ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛

рдЙрдкрд░реЛрдХреНрдд рд╡рд┐рдзрд┐ рдЙрди рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИ рдЬрдм рдЧреНрд░рд╛рд╣рдХ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдореЛрдмрд╛рдЗрд▓ рдбрд┐рд╡рд╛рдЗрд╕ рд╣реИ рдФрд░ рдХреЗрд╡рд▓ REST рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдЕрдиреБрд░реЛрдзреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реИред
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рд░реЗрд╕реНрдЯ рдЕрдиреБрд░реЛрдз рдмрдЪрд╛рд╡ рдореЗрдВ рдЖрддреЗ рд╣реИрдВред

рдЗрд╕рд▓рд┐рдП, рд╣рдо рдкрд┐рдЫрд▓реЗ рдПрдХ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдореЗрдВ рд╕рдорд╛рди рд╕реЗрд╡рд╛ рдмрдирд╛рдПрдВрдЧреЗ, рдЬреЛ рдХреЗрд╡рд▓ REST рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИред
рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдореЙрдбрд▓ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЕрдиреБрд░реЛрдз рдореЗрдВ рджреЛ рднрд╛рдЧ рд╣реЛрддреЗ рд╣реИрдВ: BeginRequestName рдФрд░ EndRequestNameред

- рдПрдХ рд╕реЗрд╡рд╛ рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП рдПрдХ ServiceContract рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ
 [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); } 

рдиреЛрдЯ: EndGetMessage рдСрдкрд░реЗрд╢рдирдХреЙрдиреНрдЯреИрдХреНрдЯ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдирд╣реАрдВ рд╣реИред

- рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд▓рд┐рдП рдПрдХ рд╡рд░реНрдЧ рдмрдирд╛рдПрдВ рдЬреЛ IAsyncResult рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ
 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; } } 

рдЬрдм рдПрдХ рдирдП рд╕рдВрджреЗрд╢ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдЖрддрд╛ рд╣реИ, рддреЛ рдПрдХ рдЕрддреБрд▓реНрдпрдХрд╛рд▓рд┐рдХ рдкрд░рд┐рдгрд╛рдо рдмрдирддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬреИрд╕реЗ рд╣реА рдЗрд╕ рдЧреНрд░рд╛рд╣рдХ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рд╕рдВрджреЗрд╢ рдЖрддрд╛ рд╣реИ, рдЗрд╕ IAsyncResult рдХреЗ рд▓рд┐рдП IsCompleted рд╕рдВрдкрддреНрддрд┐ рд╕рд╣реА рдкрд░ рд╕реЗрдЯ рд╣реЛ рдЬрд╛рддреА рд╣реИ, рдФрд░ EndGetMessage рд╡рд┐рдзрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред EndGetMessage рдЧреНрд░рд╛рд╣рдХ рдХреЛ рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рднреЗрдЬрддрд╛ рд╣реИред

- рдпрд╣ web.config рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╕реЗрд╡рд╛ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИ
 <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/In128634/


All Articles