需求:有时后比如WPF,WinForm,Windows服务这些程序可能需要对外提供接口用于第三方服务主动通信,调用推送一些服务或者数据。
想到的部分实现方式:
一、使用Socket/WebSocket通信
二、使用消息队列(比如rabbitmq)
三、使用RPC框架(比如gRPC)
四、使用http协议的方式
五、当然也可以使用数据库或者本地文件等形式实现不过这种太不好了
本文就是采用第四种对外提供接口,代码很简单就是使用.net里的System.Net命名空间下的HttpListener就可以实现Http协议的Server端
下面是服务端一个实现代码
1 using Newtonsoft.Json; 2 using System; 3 using System.Collections.Generic; 4 using System.IO; 5 using System.Linq; 6 using System.Net; 7 using System.Text; 8 using System.Threading.Tasks; 9 10 namespace WpfHttpServer 11 { 12 public class HttpServerService 13 { 14 private static bool isExcute = true; 15 private static HttpListener listener = new HttpListener(); 16 public static void Start() 17 { 18 System.Threading.ThreadPool.QueueUserWorkItem(w => Excute());//单独开启一个线程执行监听消息 19 } 20 21 private static void Excute() 22 { 23 if (HttpListener.IsSupported) 24 { 25 if (!listener.IsListening) 26 { 27 listener.Prefixes.Add("http://127.0.0.1:8888/"); //添加需要监听的url 28 listener.Start(); //开始监听端口,接收客户端请求 29 } 30 while (isExcute) 31 { 32 try 33 { 34 //阻塞主函数至接收到一个客户端请求为止 等待请求 35 HttpListenerContext context = listener.GetContext(); 36 //解析请求 37 HttpListenerRequest request = context.Request; 38 //构造响应 39 HttpListenerResponse response = context.Response; 40 //http请求方式:get,post等等 41 string httpMethod = request.HttpMethod?.ToLower(); 42 string rawUrl = request.RawUrl;//不包括IP和端口 43 var Url = request.Url;//全路径 44 45 if (httpMethod == "get") 46 { 47 //获取查询参数 48 var queryString = request.QueryString; 49 // 请求接口 test/method?id=5 50 //键值对方式 string val = queryString["key"]; 51 //string val = queryString["id"];val的值是5 52 } 53 else if (httpMethod == "post") 54 { 55 //请求接口 test/postMethod 格式是json 56 //{ 57 // "id":5, 58 // "name":"zs" 59 //} 60 //获取pots请求的请求体,json格式的字符串 61 var reader = new StreamReader(request.InputStream); 62 var questBody = reader.ReadToEnd(); 63 if (!string.IsNullOrEmpty(rawUrl)) 64 { 65 //这里可以直接用switch这个只是demo 66 if (rawUrl.Equals("/server/uploadgenconnected", StringComparison.OrdinalIgnoreCase)) 67 { 68 if (!string.IsNullOrEmpty(questBody)) 69 { 70 UploadGenConnectedModel model = JsonConvert.DeserializeObject<UploadGenConnectedModel>(questBody); 71 if (model != null) 72 { 73 // To Do 74 } 75 } 76 77 } 78 } 79 } 80 81 var responseString = string.Empty; 82 83 // 执行其他业务逻辑 84 //***************** 85 86 responseString = JsonConvert.SerializeObject(new { code = 1, msg = "发送成功" }); 87 byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString); 88 //对客户端输出相应信息. 89 response.ContentLength64 = buffer.Length; 90 //response.StatusCode = 200; 91 //response.ContentType = "text/plain"; 92 //发送响应 93 using (System.IO.Stream output = response.OutputStream) 94 { 95 output.Write(buffer, 0, buffer.Length); 96 } 97 } 98 catch (Exception exceotion) 99 { 100 //Logger.Error("处理消息异常", exceotion); 101 string str = exceotion.Message; 102 } 103 } 104 } 105 else 106 { 107 //Logger.Info("系统不支持HttpListener"); 108 } 109 } 110 111 public static void Stop() 112 { 113 isExcute = false; 114 if (listener.IsListening) 115 listener.Stop(); 116 } 117 118 } 119 120 public class UploadGenConnectedModel 121 { 122 public bool GenConnected { get; set; } 123 } 124 125 }
服务启动时需要启动监听,服务停止时需要停止监听
1 /// <summary> 2 /// App.xaml 的交互逻辑 3 /// </summary> 4 public partial class App : Application 5 { 6 public App() 7 { 8 HttpServerService.Start(); 9 } 10 }
文章主要参考:https://www.cnblogs.com/pudefu/p/9512326.html
粗略参考
https://www.cnblogs.com/uu102/archive/2013/02/16/2913410.html
https://www.cnblogs.com/tuyile006/p/11857590.html
https://www.cnblogs.com/GreenShade/p/10915023.html
https://blog.csdn.net/crystalcs2010/article/details/107937472