2010-12-03 11 views
10

के साथ मैं ज़ीरोएमक्यू के साथ प्रयोग कर रहा हूं और कुछ काम करने की कोशिश कर रहा हूं। मेरा पहला विचार यह था कि मैं दो थ्रेड के बीच संदेश भेज सकता हूं या नहीं, यह देखने के लिए इंप्रोक ट्रांसपोर्ट का उपयोग करके एक आरईपी/आरईक्यू स्थापित करना था। नीचे दिए गए अधिकांश कोड clzmq उदाहरणों से लिया गया है, लेकिन ऐसा लगता है कि यह काम नहीं करता है।ज़ीरोएमक्यू का उपयोग सी # के साथ इनप्रोक ट्रांसपोर्ट

सर्वर और ग्राहक दोनों परिवहन के लिए बाध्य हैं, लेकिन जब ग्राहक Send करने की कोशिश करता है तो यह ब्लॉक करता है और बस वहां बैठता है। मेरे पास कोई ज़ीरोएमक्यू अनुभव नहीं है इसलिए मुझे यकीन नहीं है कि पहले कहां देखना है, किसी भी मदद की सराहना की जाएगी। यहाँ हमलावर (आक्रामक) कोड है:

using System; 
using System.Diagnostics; 
using System.Threading; 
using NUnit.Framework; 
using ZMQ; 

namespace PostBox 
{ 
    [TestFixture] 
    public class Class1 
    { 

     private const string Address = "inproc://test"; 
     private const uint MessageSize = 10; 
     private const int RoundtripCount = 100; 

     [Test] 
     public void Should() 
     { 
      var clientThread = new Thread(StartClient); 
      clientThread.Start(); 

      var serverThread = new Thread(StartServer); 
      serverThread.Start(); 

      clientThread.Join(); 
      serverThread.Join(); 

      Console.WriteLine("Done with life"); 
     } 

     private void StartServer() 
     { 


      // Initialise 0MQ infrastructure 
      using (var ctx = new Context(1)) 
      { 
       using (var skt = ctx.Socket(SocketType.REP)) 
       { 
        skt.Bind(Address); 

        Console.WriteLine("Server has bound"); 

        // Bounce the messages. 
        for (var i = 0; i < RoundtripCount; i++) 
        { 
         var msg = skt.Recv(); 
         Debug.Assert(msg.Length == MessageSize); 
         skt.Send(msg); 
        } 
        Thread.Sleep(1000); 
       } 
      } 

      Console.WriteLine("Done with server"); 
     } 

     private void StartClient() 
     { 
      Thread.Sleep(2000); 

      // Initialise 0MQ infrastructure 
      using (var ctx = new Context(1)) 
      { 
       using (var skt = ctx.Socket(SocketType.REQ)) 
       { 
        skt.Bind(Address); 

        Console.WriteLine("Client has bound"); 

        // Create a message to send. 
        var msg = new byte[MessageSize]; 

        // Start measuring the time. 
        var watch = new Stopwatch(); 
        watch.Start(); 

        // Start sending messages. 
        for (var i = 0; i < RoundtripCount; i++) 
        { 
         skt.Send(msg); 
         msg = skt.Recv(); 
         Debug.Assert(msg.Length == MessageSize); 

         Console.Write("."); 
        } 

        // Stop measuring the time. 
        watch.Stop(); 
        var elapsedTime = watch.ElapsedTicks; 

        // Print out the test parameters. 
        Console.WriteLine("message size: " + MessageSize + " [B]"); 
        Console.WriteLine("roundtrip count: " + RoundtripCount); 

        // Compute and print out the latency. 
        var latency = (double)(elapsedTime)/RoundtripCount/2 * 
         1000000/Stopwatch.Frequency; 
        Console.WriteLine("Your average latency is {0} [us]", 
         latency.ToString("f2")); 
       } 
      } 

      Console.WriteLine("Done with client"); 
     } 

    } 
} 

संपादित करें:

लिए मैंने नीचे इस सवाल का जवाब की मदद से काम कर रहा है, लेकिन यह भी एक Connect करने के लिए एक Bind बदलने के लिए है, जो भावना जब बनाता है मुझे आवश्यक आप इसके बारे में सोचते हैं क्योंकि हमारे पास एक स्थानीय परिवहन और रिमोट ट्रांसपोर्ट से जुड़े क्लाइंट के लिए बाध्यकारी सर्वर है। यहां अपडेट किया गया कोड है:

using System; 
using System.Diagnostics; 
using System.Threading; 
using NUnit.Framework; 
using ZMQ; 

namespace PostBox 
{ 
    [TestFixture] 
    public class Class1 
    { 

     private const string Address = "inproc://test"; 
     private const uint MessageSize = 10; 
     private const int RoundtripCount = 100; 

     private static Context ctx; 

     [Test] 
     public void Should() 
     { 
      using (ctx = new Context(1)) 
      { 
       var clientThread = new Thread(StartClient); 
       clientThread.Start(); 

       var serverThread = new Thread(StartServer); 
       serverThread.Start(); 

       clientThread.Join(); 
       serverThread.Join(); 

       Console.WriteLine("Done with life"); 
      } 
     } 

     private void StartServer() 
     { 
      try 
      { 
       using (var skt = ctx.Socket(SocketType.REP)) 
       { 
        skt.Bind(Address); 

        Console.WriteLine("Server has bound"); 

        // Bounce the messages. 
        for (var i = 0; i < RoundtripCount; i++) 
        { 
         var msg = skt.Recv(); 
         Debug.Assert(msg.Length == MessageSize); 
         skt.Send(msg); 
        } 
        Thread.Sleep(1000); 
       } 

       Console.WriteLine("Done with server"); 
      } 
      catch (System.Exception e) 
      { 
       Console.WriteLine(e.Message); 
      } 
     } 

     private void StartClient() 
     { 
      Thread.Sleep(2000); 

      try 
      { 
       // Initialise 0MQ infrastructure 
       using (var skt = ctx.Socket(SocketType.REQ)) 
       { 
        skt.Connect(Address); 

        Console.WriteLine("Client has bound"); 

        // Create a message to send. 
        var msg = new byte[MessageSize]; 

        // Start measuring the time. 
        var watch = new Stopwatch(); 
        watch.Start(); 

        // Start sending messages. 
        for (var i = 0; i < RoundtripCount; i++) 
        { 
         skt.Send(msg); 
         msg = skt.Recv(); 
         Debug.Assert(msg.Length == MessageSize); 

         Console.Write("."); 
        } 

        // Stop measuring the time. 
        watch.Stop(); 
        var elapsedTime = watch.ElapsedTicks; 

        // Print out the test parameters. 
        Console.WriteLine("message size: " + MessageSize + " [B]"); 
        Console.WriteLine("roundtrip count: " + RoundtripCount); 

        // Compute and print out the latency. 
        var latency = (double)(elapsedTime)/RoundtripCount/2 * 
            1000000/Stopwatch.Frequency; 
        Console.WriteLine("Your average latency is {0} [us]", 
             latency.ToString("f2")); 
       } 

       Console.WriteLine("Done with client"); 
      } 
      catch (System.Exception e) 
      { 
       Console.WriteLine(e.Message); 
      } 
     } 

    } 
} 

उत्तर

14

मेरा मानना ​​है कि दोनों धागे को एक ही संदर्भ का उपयोग करने की आवश्यकता है। ज़ीरोम गाइड एक प्रक्रिया में एक से अधिक संदर्भों का उपयोग न करने की सलाह देता है। एक संदर्भ बनाएँ, दोनों धागे के बीच उस संदर्भ को साझा करें। यह काम करना चाहिए।

http://zguide.zeromq.org/chapter:all

आप अपने प्रक्रिया के लिए एक 'संदर्भ' वस्तु बनाने चाहिए, और सभी धागे है कि पारित से

। संदर्भ ØMQ के राज्य को एकत्र करता है। कनेक्शन में कनेक्शन बनाने के लिए: परिवहन, सर्वर और क्लाइंट थ्रेड दोनों को एक ही संदर्भ ऑब्जेक्ट साझा करना होगा।

+0

यह बहुत उपयोगी था, धन्यवाद! – jonnii

2

केवल एक अंत दूसरे को जोड़ना चाहिए, कनेक्ट हो सकता है, आप एकाधिक कनेक्शन प्राप्त कर सकते हैं।

संबंधित मुद्दे