클라이언트 서버 예제 3
서버 > 중간프로그램 > 디바이스 로 전송/수신 되는 프로그램이며,
외부 프로그램은 서버와 디바이스이고, 중간프로그램이 아래 동작 코드이다.
아래 코드는 서버에서 아래 형태의 Json 데이터를 받으면
{"command":"CMD_002","targetDevice":["DEVICE_083","DEVICE_015"],"param":"ce3c39e1"}
device.json 파일에서 아래 정보를 읽은 후
{ "deviceInfo":[
{"device":"DEVICE_069", "hostname":"127.0.0.1", "port":9010},
{"device":"DEVICE_083", "hostname":"127.0.0.1", "port":9020},
{"device":"DEVICE_015", "hostname":"127.0.0.1", "port":9030}
]
}
server_command.json 에서 아래 정보를 읽은 후
{ "serverCommandInfo":[
{"command":"CMD_001", "forwardCommand":"CMD_001_A"},
{"command":"CMD_002", "forwardCommand":"CMD_002_B"}
]
}
조합하여 아래형식으로 디바이스로 전달 한다.
{"command":"CMD_002_B","param":"ce3c39e1"}
서버전송은 아래 정보를 참고한다.
구분 URI
Server로부터의 Request POST http://127.0.0.1:8010/ fromServer
Device로의 Request POST http://<Device hostname>:<Device port>/ fromEdge
그러면 아래 형식으로 response를 받게 되고,
Device 083 응답 : {"result":["c8d4fc55"]}
Device 015 응답 : {"result":["9604d2cd"]}
디바이스 별로 전달되는 것을 취합하여 아래형식으로 최종 서버에 응답한다.
{"result":["c8d4fc55","9604d2cd"]}
using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Text; using System.Threading; namespace SP_TEST { class DeviceInfo { public string device = null; public string hostname = null; public int port = 0; } class Program { // Command Info 관리 리스트 static Dictionary<string, string> CmdInfo = new Dictionary<string, string>(); static Dictionary<string, DeviceInfo> dicDeviceInfo = new Dictionary<string, DeviceInfo>(); static void Main(string[] args) { //// 파일로부터 Command Info 읽어오기 LoadCmdInfo(); LoadDeviceInfo(); HttpListener listener = new HttpListener(); listener.Prefixes.Add("http://127.0.0.1:8010/"); listener.Start(); while (true) { var context = listener.GetContext(); Console.WriteLine(string.Format(">>>>>>>>>>>>>>[{0}] Request({1}) : {2}", DateTime.Now.ToString("hh:mm:ss.fff"), context.Request.HttpMethod, context.Request.Url)); Thread th = new Thread(Http_Server); th.Start(context); } } static void Http_Server(Object obj) { string strRes = null; HttpListenerContext context = (HttpListenerContext)obj; Console.WriteLine("Http_Server Thread Start : " + context.Request.RawUrl); StreamReader sr = new StreamReader(context.Request.InputStream); JObject body = JObject.Parse(sr.ReadToEnd()); sr.Close(); Console.WriteLine("body : " + body); switch (context.Request.RawUrl) { case "/fromServer": strRes = sendToDevices(body["command"].ToString(), body["param"].ToString(), body["targetDevice"].ToObject<List<string>>()); break; default: Console.WriteLine("error"); break; } if (strRes != null) { byte[] data = Encoding.UTF8.GetBytes(strRes); context.Response.OutputStream.Write(data, 0, data.Length); } context.Response.StatusCode = 200; context.Response.Close(); } static string sendToDevices(string command, string param, List<string> targetDevice) { JObject jRes = new JObject(); jRes["result"] = new JArray(); // device들로부터 전달되는 결과값들 foreach (string deviceId in targetDevice) { string forwardCommand = CmdInfo[command]; JObject deviceRet = sendToDevice(deviceId, forwardCommand, param); ((JArray)jRes["result"]).Add(deviceRet.GetValue("result").First); } return jRes.ToString(); } // 특정 device에 command 전송 static JObject sendToDevice(string device, string command, string param) { string url = string.Format("http://{0}:{1}/fromEdge", dicDeviceInfo[device].hostname, dicDeviceInfo[device].port); HttpClient client = new HttpClient(); HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, url); dynamic body = new JObject(); body.command = command; body.param = param; Console.WriteLine($"Send to device : {url}, {body}"); httpRequestMessage.Content = new StringContent(body.ToString(), Encoding.UTF8, "application/json"); var res = client.SendAsync(httpRequestMessage).Result; string strRes = res.Content.ReadAsStringAsync().Result; Console.WriteLine($"Response : {strRes}"); return JObject.Parse(strRes); } // 파일로부터 Command Info 사용하기 쉽게 읽어오기 static void LoadCmdInfo() { JObject jObj = JObject.Parse(File.ReadAllText(".\\INFO\\SERVER_COMMAND.JSON")); foreach (JObject cmd in jObj["serverCommandInfo"]) { CmdInfo[cmd["command"].ToString()] = cmd["forwardCommand"].ToString(); } } // 파일로부터 Device Info 사용하기 쉽게 읽어오기 static void LoadDeviceInfo() { JObject jObj = JObject.Parse(File.ReadAllText(".\\INFO\\DEVICE.JSON")); foreach (JObject device in jObj["deviceInfo"]) { DeviceInfo deviceInfo = device.ToObject<DeviceInfo>(); dicDeviceInfo.Add(deviceInfo.device, deviceInfo); } } } } |