/// <summary> /// 命令解包 /// </summary> /// <param name="showError"></param> /// <param name="messages"></param> /// <returns></returns> public static ZeroResultData Unpack(this ZMessage messages, bool showError = false) { try { var description = messages[0].Read(); if (description.Length == 0) { if (showError) { ZeroTrace.WriteError("Unpack", "LaoutError", description.LinkToString(p => p.ToString("X2"), "")); } return(new ZeroResultData { State = ZeroOperatorStateType.FrameInvalid, Message = "网络格式错误" }); } int end = description[0] + 1; if (end != messages.Count) { if (showError) { ZeroTrace.WriteError("Unpack", "LaoutError", $"FrameSize{messages.Count}", description.LinkToString(p => p.ToString("X2"), "")); } return(new ZeroResultData { State = ZeroOperatorStateType.FrameInvalid, Message = "网络格式错误" }); } var result = new ZeroResultData { InteractiveSuccess = true, State = (ZeroOperatorStateType)description[1] }; for (int idx = 1; idx < end; idx++) { result.Add(description[idx + 1], Encoding.UTF8.GetString(messages[idx].Read())); } return(result); } catch (Exception e) { ZeroTrace.WriteException("Unpack", e); return(new ZeroResultData { State = ZeroOperatorStateType.LocalRecvError, Exception = e }); } finally { messages.Dispose(); } }
private T DeserializeMessage <T>(ZMessage msg) where T : class { T t = null; ByteArrayPool _bytePool = new ByteArrayPool(); byte[] tmp = _bytePool.Malloc((int)(msg[1].Length)); msg[1].Read(tmp, 0, (int)(msg[1].Length)); using (System.IO.MemoryStream stream = new System.IO.MemoryStream(tmp)) { System.Runtime.Serialization.Formatters.Binary.BinaryFormatter fmt = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); t = fmt.Deserialize(stream) as T; } _bytePool.Free(tmp); //try //{ // t = CommonUtils.FromJSON<T>(msg[1].ReadString()); //} //catch (Exception ex) //{ // Program.logger.LogRunning("反序列化市场数据失败!\r\n Message:{0}\r\n StackTrace:{1}", ex.Message, ex.StackTrace); //} msg.Dispose(); return(t); }
public static void TIClient(string[] args) { bool verbose = (args.Any(e => e.ToLower().Equals("-v") || e.ToLower().Equals("--verbose"))); Console.WriteLine("Verbose: {0}", verbose); CancellationTokenSource cancellor = new CancellationTokenSource(); Console.CancelKeyPress += (s, ea) => { ea.Cancel = true; cancellor.Cancel(); }; using (MajordomoClient session = new MajordomoClient("tcp://localhost:5555", verbose)) { // 1. Send 'echo' request to Titanic ZMessage request = new ZMessage(); request.Add(new ZFrame("echo")); request.Add(new ZFrame("Hello World")); Guid uuid = Guid.Empty; using (var reply = TIClient_ServiceCall(session, "titanic.request", request, cancellor)) { if (reply != null) { uuid = Guid.Parse(reply.PopString()); "I: request UUID {0}".DumpString(uuid); } } // 2. Wait until we get a reply while (!cancellor.IsCancellationRequested) { Thread.Sleep(100); request.Dispose(); request = new ZMessage(); request.Add(new ZFrame(uuid.ToString())); var reply = TIClient_ServiceCall(session, "titanic.reply", request, cancellor); if (reply != null) { string replystring = reply.Last().ToString(); "Reply: {0}\n".DumpString(replystring); reply.Dispose(); // 3. Close Request request.Dispose(); request = new ZMessage(); request.Add(new ZFrame(uuid.ToString())); reply = TIClient_ServiceCall(session, "titanic.close", request, cancellor); reply.Dispose(); break; } else { "I: no reply yet, trying again...\n".DumpString(); Thread.Sleep(5000); // try again in 5 seconds } } } }
// MMI echo query example public static void MMIEcho(string[] args) { bool verbose = (args.Any(e => e.ToLower().Equals("-v") || e.ToLower().Equals("--verbose"))); Console.WriteLine("Verbose: {0}", verbose); CancellationTokenSource cancellor = new CancellationTokenSource(); Console.CancelKeyPress += (s, ea) => { ea.Cancel = true; cancellor.Cancel(); }; using (MajordomoClient session = new MajordomoClient("tcp://localhost:5555", verbose)) { ZMessage request = new ZMessage(); request.Add(new ZFrame("echo")); ZMessage reply = session.Send("mmi.service", request, cancellor); if (reply != null) { var replycode = reply[0].ToString(); "Loopup echo service: {0}\n".DumpString(replycode); reply.Dispose(); } else { "E: no response from broker, make sure it's running\n".DumpString(); } } }
// MMI echo query example public static void MMIEcho(string[] args) { CancellationTokenSource cancellor = new CancellationTokenSource(); Console.CancelKeyPress += (s, ea) => { ea.Cancel = true; cancellor.Cancel(); }; using (MajordomoClient session = new MajordomoClient("tcp://127.0.0.1:5555", Verbose)) { ZMessage request = new ZMessage(); request.Add(new ZFrame("echo")); ZMessage reply = session.Send("mmi.service", request, cancellor); if (reply != null) { var replycode = reply[0].ToString(); "Loopup echo service: {0}\n".DumpString(replycode); reply.Dispose(); } else { "E: no response from broker, make sure it's running\n".DumpString(); } } }
public static void TIClient(string[] args) { CancellationTokenSource cancellor = new CancellationTokenSource(); Console.CancelKeyPress += (s, ea) => { ea.Cancel = true; cancellor.Cancel(); }; using (MajordomoClient session = new MajordomoClient("tcp://127.0.0.1:5555", Verbose)) { // 1. Send 'echo' request to Titanic ZMessage request = new ZMessage(); request.Add(new ZFrame("echo")); request.Add(new ZFrame("Hello World")); Guid uuid = Guid.Empty; using (var reply = TIClient_ServiceCall(session, "titanic.request", request, cancellor)) { if (reply != null) { uuid = Guid.Parse(reply.PopString()); "I: request UUID {0}".DumpString(uuid); } } // 2. Wait until we get a reply while (!cancellor.IsCancellationRequested) { Thread.Sleep(100); request.Dispose(); request = new ZMessage(); request.Add(new ZFrame(uuid.ToString())); var reply = TIClient_ServiceCall(session, "titanic.reply", request, cancellor); if (reply != null) { string replystring = reply.Last().ToString(); "Reply: {0}\n".DumpString(replystring); reply.Dispose(); // 3. Close Request request.Dispose(); request = new ZMessage(); request.Add(new ZFrame(uuid.ToString())); reply = TIClient_ServiceCall(session, "titanic.close", request, cancellor); reply.Dispose(); break; } else { "I: no reply yet, trying again...\n".DumpString(); Thread.Sleep(5000); // try again in 5 seconds } } } }
// .split try to call a service // Here, we first check if the requested MDP service is defined or not, // using a MMI lookup to the Majordomo broker. If the service exists, // we send a request and wait for a reply using the conventional MDP // client API. This is not meant to be fast, just very simple: static bool Titanic_ServiceSuccess(Guid uuid, CancellationTokenSource cts) { // Load request message, service will be first frame string fn = TitanicCommon.RequestFilename(uuid); FileStream fs; if (!fn.TryFileOpenRead(out fs)) { // If the client already close request, treat as successful return(true); } fs.Dispose(); ZMessage request = fn.DeserializeFromXml <ZMessage>(); var service = request.Pop(); string servicename = service.ToString(); bool res = false; // Create MDP client session with short timeout using (var client = new MajordomoClient("tcp://127.0.0.1:5555", false)) { client.Set_Timeout(1000); // 1sec client.Set_Retries(1); // only 1 retry // Use MMI protocol to check if service is available ZMessage mmirequest = new ZMessage { service }; bool service_ok; using (var mmireply = client.Send("mmi.service", mmirequest, cts)) service_ok = (mmireply != null && mmireply.First().ToString().Equals("200")); res = false; if (service_ok) { using (ZMessage reply = client.Send(servicename, request, cts)) if (reply != null) { fn = TitanicCommon.ReplyFilename(uuid); reply.SerializeToXml(fn); res = true; } else { request.Dispose(); } } } return(res); }
public static void FLClient2(string[] args) { if (args == null || args.Length < 1) { Console.WriteLine(); Console.WriteLine("Usage: ./{0} FLClient2 [Endpoint] ...", AppDomain.CurrentDomain.FriendlyName); Console.WriteLine(); Console.WriteLine(" Endpoint Where FLClient2 should connect to."); Console.WriteLine(" Default is tcp://127.0.0.1:7781"); Console.WriteLine(); args = new string[] { "tcp://127.0.0.1:7781" }; } // Create new freelance client object using (var client = new FLClient()) { // Connect to each endpoint for (int i = 0; i < args.Length; ++i) { client.Connect(args[i]); } // Send a bunch of name resolution 'requests', measure time int requests = 0; DateTime starttime = DateTime.UtcNow; var error = ZError.None; while (++requests < 10000) { var outgoing = new ZMessage(); outgoing.Add(new ZFrame("random name")); ZMessage incoming = client.Request(outgoing); if (incoming == null) { error = ZError.ETERM; break; } incoming.Dispose(); // using (incoming) ; } if (error == ZError.ETERM) { Console.WriteLine("E: name service not available, aborted."); } else { Console.WriteLine("Average round trip cost: {0} ms", (DateTime.UtcNow - starttime).TotalMilliseconds / requests); } } }
//public AASServiceReference private static string SendRequest(ZSocket socket, string strRequest) { ZMessage msgRequest = new ZMessage(); msgRequest.Add(new ZFrame(strRequest)); socket.Send(msgRequest); msgRequest.Dispose(); ZMessage msgReceive = socket.ReceiveMessage(); string strReceive = msgReceive[0].ReadString(); return(strReceive); }
public static T DeserializeMessage <T>(ZMessage msg) where T : class { T t = null; ByteArrayPool _bytePool = new ByteArrayPool(); byte[] tmp = _bytePool.Malloc((int)(msg[1].Length)); msg[1].Read(tmp, 0, (int)(msg[1].Length)); using (System.IO.MemoryStream stream = new System.IO.MemoryStream(tmp)) { System.Runtime.Serialization.Formatters.Binary.BinaryFormatter fmt = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); t = fmt.Deserialize(stream) as T; } _bytePool.Free(tmp); msg.Dispose(); return(t); }
// .split Titanic request service // The {{titanic.request}} task waits for requests to this service. It writes // each request to disk and returns a UUID to the client. The client picks // up the reply asynchronously using the {{titanic.reply}} service: private static void Titanic_Request(ZContext ctx, ZSocket backendpipe, CancellationTokenSource cancellor, object[] args) { using (MajordomoWorker worker = new MajordomoWorker("tcp://127.0.0.1:5555", "titanic.request", (bool)args[0])) { ZMessage reply = null; while (true) { // Send reply if it's not null // And then get next request from broker ZMessage request = worker.Recv(reply, cancellor); if (request == null) { break; // Interrupted, exit } // Ensure message directory exists Directory.CreateDirectory(TitanicCommon.TITANIC_DIR); // Generate UUID and save mesage to disk Guid uuid = TitanicCommon.GenerateUuid(); string fn = TitanicCommon.RequestFilename(uuid); request.SerializeToXml(fn); request.Dispose(); // Send UUID through tho message queue reply = new ZMessage(); reply.Add(new ZFrame(uuid.ToString())); ZError error; if (!backendpipe.Send(reply, out error)) { if (error.Equals(ZError.ETERM)) { break; } } //backendpipe.Send(reply); // Now send UUID back to client // Done by the mdwrk_recv() at the top of the loop reply = new ZMessage(); reply.Add(new ZFrame("200")); reply.Add(new ZFrame(uuid.ToString())); } } }
private void ReplyMain() { using (ZSocket socket = new ZSocket(context, ZSocketType.REP)) { try { socket.Bind(string.Format("tcp://*:{0}", Port)); Program.logger.LogInfoDetail("额度管理通讯接口正常开启,端口:{0}。", Port); } catch (Exception ex) { Program.logger.LogInfoDetail("额度管理通讯接口 Binding Exception:\r\n bind info: {0}\r\n Exception Message: {1}\r\n StackTrace:{2}", Port, ex.Message, ex.StackTrace); return; } while (true) { var msgReceive = socket.ReceiveMessage(); ZMessage zMsgReply = new ZMessage(); string strReceive = null; try { if (msgReceive != null) { strReceive = msgReceive[0].ReadString(); //Program.logger.LogInfoDetail("3.额度管理通讯接口收到新消息,内容{0}", strReceive); SwitchMessage(zMsgReply, strReceive); msgReceive.Dispose(); } else { zMsgReply.Add(new ZFrame("无效:消息为空!")); } } catch (Exception ex) { zMsgReply.Add(new ZFrame(string.Format("4|额度管理功能异常, 收到Message:{0}, Exception {1}", strReceive, ex.Message))); } socket.Send(zMsgReply); zMsgReply.Dispose(); } } }
private string GetGuid(ZSocket socket) { string guid = null; ZMessage msgSend = new ZMessage(); msgSend.Add(new ZFrame("0|" + ServiceConnectHelper.ConnectionKey)); try { socket.Send(msgSend); msgSend.Dispose(); var msgReceive = socket.ReceiveMessage(); socket.ReceiveTimeout = new TimeSpan(0, 0, 3); if (msgReceive != null) { var strMsg = msgReceive[0].ReadString(); if (strMsg.StartsWith("0|1|")) { guid = strMsg.Substring(4); this.IsConnected = true; } else { Utils.Log("获取连接ID失败!"); } } } catch (ZeroMQ.ZException) { Status = "连接异常,请尝试手动重新连接"; Thread.CurrentThread.Abort(); } catch (Exception ex) { Utils.Log("获取连接ID异常!", ex); Status = "连接异常!" + ex.Message; } return(guid); }
private void RepMain() { string RepPort = Utils.GetConfig("REP_PORT"); using (ZSocket socket = new ZSocket(context, ZSocketType.REP)) { try { socket.Bind(string.Format("tcp://*:{0}", RepPort)); Utils.logger.LogInfo("ZeroMQ Replay接口正常开启,端口:{0}。", RepPort); } catch (Exception) { Utils.logger.LogInfo("ZeroMQ Replay接口正常开启,端口:{0}。", RepPort); return; } while (true) { var msg = socket.ReceiveMessage(); ZMessage zMsgReply = new ZMessage(); string message = null; try { message = msg[0].ReadString(); var result = SwitchMessage(message); zMsgReply.Add(new ZFrame(result)); } catch (Exception ex) { string ExceptionInfo = string.Format("RepMain Exception, Message:{0}", ex.Message); Utils.logger.LogInfo(ExceptionInfo); zMsgReply.Add(new ZFrame(ExceptionInfo)); } socket.Send(zMsgReply); zMsgReply.Dispose(); } } }
private void Heartbreak(ZSocket socket) { var msgSend = new ZMessage(); msgSend.Add(new ZFrame("10|" + ConnectGUID)); try { socket.ReceiveTimeout = new TimeSpan(0, 0, 3); socket.Send(msgSend); msgSend.Dispose(); var msgReceive = socket.ReceiveMessage(); string strReceive = msgReceive[0].ReadString(); if (!strReceive.Contains("10|1|")) { this.ConnectGUID = null; this.IsConnected = false; Status = strReceive; } else { Status = "已连接"; } } catch (ZeroMQ.ZException ex) { this.ConnectGUID = null; this.IsConnected = false; Status = "连接异常," + ex.Message; Thread.CurrentThread.Abort(); } catch (Exception) { this.ConnectGUID = null; this.IsConnected = false; Status = "连接异常"; } }
// .split Titanic close task // The {{titanic.close}} task removes any waiting replies for the request // (specified by UUID). It's idempotent, so it is safe to call more than // once in a row: private static void Titanic_Close(ZContext context, CancellationTokenSource cts, bool verbose) { using (var worker = new MajordomoWorker("tcp://127.0.0.1:5555", "titanic.close", verbose)) { ZMessage reply = null; while (true) { ZMessage request = worker.Recv(reply, cts); if (request == null) { break; } var g = Guid.Parse(request.Pop().ReadString()); var reqfn = TitanicCommon.RequestFilename(g); var repfn = TitanicCommon.ReplyFilename(g); File.Delete(reqfn); File.Delete(repfn); request.Dispose(); reply = new ZMessage(); reply.Add(new ZFrame("200")); } } }
// .split send request and wait for reply // Here is the {{send}} method. It sends a request to the broker and gets // a reply even if it has to retry several times. It takes ownership of // the request message, and destroys it when sent. It returns the reply // message, or NULL if there was no reply after multiple attempts: public ZMessage Send(string service, ZMessage request, CancellationTokenSource cancellor) { if (request == null) { throw new InvalidOperationException(); } // Prefix request with protocol frames // Frame 1: "MDPCxy" (six bytes, MDP/Client x.y) // Frame 2: Service name (printable string) request.Prepend(new ZFrame(service)); request.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT)); if (Verbose) { request.DumpZmsg("I: send request to '{0}' service:", service); } int retriesLeft = Retries; while (retriesLeft > 0 && !cancellor.IsCancellationRequested) { if (cancellor.IsCancellationRequested || (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape)) { _context.Shutdown(); } // Copy the Request and send on Client ZMessage msgreq = request.Duplicate(); ZError error; if (!Client.Send(msgreq, out error)) { if (Equals(error, ZError.ETERM)) { cancellor.Cancel(); break; // Interrupted } } var p = ZPollItem.CreateReceiver(); ZMessage msg; // .split body of send // On any blocking call, {{libzmq}} will return -1 if there was // an error; we could in theory check for different error codes, // but in practice it's OK to assume it was {{EINTR}} (Ctrl-C): // Poll the client Message if (Client.PollIn(p, out msg, out error, Timeout)) { // If we got a reply, process it if (Verbose) { msg.DumpZmsg("I: received reply"); } if (msg.Count < 3) { throw new InvalidOperationException(); } using (ZFrame header = msg.Pop()) if (!header.ToString().Equals(MdpCommon.MDPC_CLIENT)) { throw new InvalidOperationException(); } using (ZFrame replyService = msg.Pop()) if (!replyService.ToString().Equals(service)) { throw new InvalidOperationException(); } request.Dispose(); return(msg); } else if (Equals(error, ZError.ETERM)) { cancellor.Cancel(); break; // Interrupted } else if (Equals(error, ZError.EAGAIN)) { if (--retriesLeft > 0) { if (Verbose) { "W: no reply, reconnecting...".DumpString(); } ConnectToBroker(); } else { if (Verbose) { "W: permanent error, abandoning".DumpString(); } break; // Give up } } } if (cancellor.IsCancellationRequested) { "W: interrupt received, killing client...\n".DumpString(); } request.Dispose(); return(null); }
public ZMessage Request(ZMessage request) { // This method does the hard work. It sends a request to all // connected servers in parallel (for this to work, all connections // must be successful and completed by this time). It then waits // for a single successful reply, and returns that to the caller. // Any other replies are just dropped: ZMessage reply = null; using (request) { // Prefix request with sequence number and empty envelope this.sequence++; request.Prepend(new ZFrame(this.sequence)); request.Prepend(new ZFrame()); // Blast the request to all connected servers for (int server = 0; server < this.servers; ++server) { using (var outgoing = request.Duplicate()) { this.socket.Send(outgoing); } } // Wait for a matching reply to arrive from anywhere // Since we can poll several times, calculate each one ZError error; DateTime endtime = DateTime.UtcNow + GLOBAL_TIMEOUT; var poll = ZPollItem.CreateReceiver(); while (endtime > DateTime.UtcNow) { if (this.socket.PollIn(poll, out reply, out error, endtime - DateTime.UtcNow)) { // Reply is [empty][sequence][OK] if (reply.Count < 3) { throw new InvalidOperationException(); } reply.RemoveAt(0); using (ZFrame sequenceFrame = reply.RemoveAt(0, false)) { int sequence = sequenceFrame.ReadInt32(); if (sequence == this.sequence) { break; // Reply is ok } } reply.Dispose(); } else { if (error == ZError.ETERM) { break; // Interrupted } if (error != ZError.EAGAIN) { throw new ZException(error); } } } } return(reply); }
//void ProcessTask(object obj) //{ // Interlocked.Increment(ref ptocessTaskCount); // var socket = ZSocket.CreateClientSocket(Config.WorkerResultAddress, ZSocketType.DEALER); // var pool = ZmqPool.CreateZmqPool(); // pool.Prepare(new[] { ZSocket.CreateClientSocket($"inproc://{StationName}_api.route", ZSocketType.PAIR) }, ZPollEvent.In); // var token = (CancellationToken)obj; // while (!token.IsCancellationRequested && CanRun) // { // //if (!Quote.StartProcess(out var item)) // //{ // // continue; // //} // //ApiCall(ref socket, item); // //Quote.EndProcess(); // if (!pool.Poll() || !pool.CheckIn(0, out var message)) // { // continue; // } // using (message) // { // if (!Unpack(message, out var item)) // { // SendLayoutErrorResult(ref socket, item.Caller, item.Requester); // continue; // } // ApiCall(ref socket, item); // } // } // socket.TryClose(); // if (Interlocked.Decrement(ref ptocessTaskCount) == 0) // _processSemaphore.Release(); //} #endregion #region IO /// <summary> /// 解析数据 /// </summary> /// <param name="messages"></param> /// <param name="item"></param> /// <returns></returns> private bool Unpack(ZMessage messages, out ApiCallItem item) { item = new ApiCallItem { Caller = messages[0].Read() }; try { var description = messages[1].Read(); if (description.Length < 2) { ZeroTrace.WriteError("Receive", "LaoutError", Config.WorkerResultAddress, description.LinkToString(p => p.ToString("X2"), "")); item = null; return(false); } int end = description[0] + 2; if (end != messages.Count) { ZeroTrace.WriteError("Receive", "LaoutError", Config.WorkerResultAddress, $"FrameSize{messages.Count}", description.LinkToString(p => p.ToString("X2"), "")); item = null; return(false); } for (int idx = 2; idx < end; idx++) { var bytes = messages[idx].Read(); if (bytes.Length == 0) { continue; } var val = Encoding.UTF8.GetString(bytes).TrimEnd('\0'); switch (description[idx]) { case ZeroFrameType.GlobalId: item.GlobalId = val; break; case ZeroFrameType.RequestId: item.RequestId = val; break; case ZeroFrameType.Requester: item.Requester = val; break; case ZeroFrameType.Context: item.ContextJson = val; break; case ZeroFrameType.Command: item.ApiName = val; break; case ZeroFrameType.Argument: item.Argument = val; break; case ZeroFrameType.Content: item.Content = val; break; } } return(item.ApiName != null && item.GlobalId != null); } catch (Exception e) { ZeroTrace.WriteException("Receive", e, Config.WorkerResultAddress, $"FrameSize{messages.Count}"); return(false); } finally { messages.Dispose(); } }
public string GetResponse(string Host, int Port, string Message, int TimeOutSeconds = 10) { var Context = new ZeroMQContext(); var Client = Context.CreateClientSocket(ZSocketType.REQ); Client.ReceiveTimeout = TimeSpan.FromSeconds(TimeOutSeconds); Client.Connect("tcp://" + Host + ":" + Port, out var connectError); string responseString = ""; if (connectError != null) { Console.WriteLine($"Connection error: {connectError.Name} - {connectError.Number} - {connectError.Text}"); return(null); } else { var requestMessage = new ZMessage(); requestMessage.Add(new ZFrame(Message)); Client.Send(requestMessage, out var sendError); if (sendError == null) { try { ZMessage response = null; bool timeout = false; DateTime sendTime = DateTime.Now; while (response == null && !timeout) { response = Client.ReceiveMessage(out var error); if (error != null) { timeout = true; Console.WriteLine($"ZeroMQ P2P Client ReadResponse error: {error.Name} - {error.Number} - {error.Text}"); } else { timeout = (DateTime.Now - sendTime).TotalSeconds > TimeOutSeconds; } } if (response != null) { responseString = response[0].ReadString(); } } catch (Exception err) { Console.WriteLine("Failed -> " + err.ToString()); } } else { Console.WriteLine($"Send error: {sendError.Name} - {sendError.Number} - {sendError.Text}"); } requestMessage.Dispose(); } Context.Dispose(); return(responseString); }
/// <summary> /// 广播消息解包 /// </summary> /// <param name="messages"></param> /// <param name="item"></param> /// <returns></returns> protected override bool Unpack(ZMessage messages, out PlanItem item) { if (messages == null) { item = null; return(false); } try { if (messages.Count < 3) { item = null; return(false); } var description = messages[1].Read(); if (description.Length < 2) { item = null; return(false); } int end = description[0] + 2; if (end != messages.Count) { item = null; return(false); } item = new PlanItem { Title = messages[0].ReadString(), State = (ZeroOperatorStateType)description[1], ZeroEvent = (ZeroNetEventType)description[1] }; for (int idx = 2; idx < end; idx++) { var bytes = messages[idx].Read(); if (bytes.Length == 0) { continue; } switch (description[idx]) { case ZeroFrameType.SubTitle: item.SubTitle = Encoding.UTF8.GetString(bytes); break; case ZeroFrameType.Station: item.Station = Encoding.UTF8.GetString(bytes); break; case ZeroFrameType.Publisher: item.Publisher = Encoding.UTF8.GetString(bytes); break; case ZeroFrameType.Context: var json = Encoding.UTF8.GetString(bytes); item.Plan = JsonConvert.DeserializeObject <ZeroPlan>(json); break; case ZeroFrameType.JsonValue: item.CallResultJson = Encoding.UTF8.GetString(bytes); break; case ZeroFrameType.Status: item.Status = bytes; break; case ZeroFrameType.BinaryValue: item.Buffer = bytes; break; case ZeroFrameType.TsonValue: item.Tson = bytes; break; default: item.Values.Add(Encoding.UTF8.GetString(bytes)); break; } } return(true); } catch (Exception e) { ZeroTrace.WriteException("Unpack", e); item = null; return(false); } finally { messages.Dispose(); } }
// .split send request and wait for reply // Here is the {{send}} method. It sends a request to the broker and gets // a reply even if it has to retry several times. It takes ownership of // the request message, and destroys it when sent. It returns the reply // message, or NULL if there was no reply after multiple attempts: public ZMessage Send(string service, ZMessage request, CancellationTokenSource cancellor) { if (request == null) throw new InvalidOperationException(); // Prefix request with protocol frames // Frame 1: "MDPCxy" (six bytes, MDP/Client x.y) // Frame 2: Service name (printable string) request.Prepend(new ZFrame(service)); request.Prepend(new ZFrame(MdpCommon.MDPC_CLIENT)); if (Verbose) request.DumpZmsg("I: send request to '{0}' service:", service); int retriesLeft = Retries; while (retriesLeft > 0 && !cancellor.IsCancellationRequested) { if (cancellor.IsCancellationRequested || (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.Escape)) _context.Shutdown(); // Copy the Request and send on Client ZMessage msgreq = request.Duplicate(); ZError error; if (!Client.Send(msgreq, out error)) { if (Equals(error, ZError.ETERM)) { cancellor.Cancel(); break; // Interrupted } } var p = ZPollItem.CreateReceiver(); ZMessage msg; // .split body of send // On any blocking call, {{libzmq}} will return -1 if there was // an error; we could in theory check for different error codes, // but in practice it's OK to assume it was {{EINTR}} (Ctrl-C): // Poll the client Message if (Client.PollIn(p, out msg, out error, Timeout)) { // If we got a reply, process it if (Verbose) msg.DumpZmsg("I: received reply"); if(msg.Count < 3) throw new InvalidOperationException(); using (ZFrame header = msg.Pop()) if (!header.ToString().Equals(MdpCommon.MDPC_CLIENT)) throw new InvalidOperationException(); using (ZFrame replyService = msg.Pop()) if(!replyService.ToString().Equals(service)) throw new InvalidOperationException(); request.Dispose(); return msg; } else if (Equals(error, ZError.ETERM)) { cancellor.Cancel(); break; // Interrupted } else if (Equals(error, ZError.EAGAIN)) { if (--retriesLeft > 0) { if (Verbose) "W: no reply, reconnecting...".DumpString(); ConnectToBroker(); } else { if (Verbose) "W: permanent error, abandoning".DumpString(); break; // Give up } } } if (cancellor.IsCancellationRequested) { "W: interrupt received, killing client...\n".DumpString(); } request.Dispose(); return null; }
private void ReplyMain() { using (ZSocket socket = new ZSocket(context, ZSocketType.REP)) { try { socket.Bind(string.Format("tcp://*:{0}", RepPort)); Program.logger.LogInfoDetail("ZeroMQ Replay接口正常开启,端口:{0}。", RepPort); } catch (Exception ex) { Program.logger.LogInfoDetail("REP Binding Exception:\r\n bind info: {0}\r\n Exception Message: {1}\r\n StackTrace:{2}", RepPort, ex.Message, ex.StackTrace); return; } while (true) { var msg = socket.ReceiveMessage(); ZMessage zMsgReply = new ZMessage(); string message = null; try { if (msg != null) { message = msg[0].ReadString(); if (message.IndexOf('|') < 0) { zMsgReply.Add(new ZFrame("Invalid Message:" + message + " " + DateTime.Now.ToString())); } else { string[] infos = message.Split('|'); if (infos[0] == "0") { Login(zMsgReply, infos[1], infos[2]); } else if (DictUserLogin.ContainsKey(infos[1])) { SwitchMessage(zMsgReply, message, infos); } else { zMsgReply.Add(new ZFrame("Invalid: Please login your account")); } } msg.Dispose(); } else { zMsgReply.Add(new ZFrame("无效:消息为空!")); } } catch (Exception ex) { zMsgReply.Add(new ZFrame(string.Format("4|自动下单功能异常, Message:{0}, Exception {1}", message, ex.Message))); //Program.logger.LogInfoDetail("自动下单功能异常:\r\n ZMessage:{0}\r\n Message:{1}\r\n StackTrace:{2}", msg[0].ReadString(), ex.Message, ex.StackTrace); } socket.Send(zMsgReply); zMsgReply.Dispose(); } } }
/// <summary> /// 广播消息解包 /// </summary> /// <param name="messages"></param> /// <param name="item"></param> /// <param name="showError"></param> /// <returns></returns> public static bool Unpack(this ZMessage messages, out PublishItem item, bool showError = true) { if (messages == null) { item = null; return(false); } try { if (messages.Count < 3) { item = null; return(false); } var description = messages[1].Read(); if (description.Length < 2) { item = null; return(false); } int end = description[0] + 2; if (end != messages.Count) { item = null; return(false); } item = new PublishItem { Title = messages[0].ReadString(), State = (ZeroOperatorStateType)description[1], ZeroEvent = (ZeroNetEventType)description[1] }; for (int idx = 2; idx < end; idx++) { var bytes = messages[idx].Read(); if (bytes.Length == 0) { continue; } switch (description[idx]) { case ZeroFrameType.SubTitle: item.SubTitle = Encoding.UTF8.GetString(bytes); break; case ZeroFrameType.Station: item.Station = Encoding.UTF8.GetString(bytes); break; case ZeroFrameType.Publisher: item.Publisher = Encoding.UTF8.GetString(bytes); break; case ZeroFrameType.Content: if (item.Content == null) { item.Content = Encoding.UTF8.GetString(bytes); } else { item.Values.Add(Encoding.UTF8.GetString(bytes)); } break; case ZeroFrameType.BinaryValue: item.Buffer = bytes; break; case ZeroFrameType.TsonValue: item.Tson = bytes; break; default: item.Values.Add(Encoding.UTF8.GetString(bytes)); break; } } return(true); } catch (Exception e) { ZeroTrace.WriteException("Unpack", e); item = null; return(false); } finally { messages.Dispose(); } }