صندوق رأس المال العامل:Net.TCP روابط متعددة، نفس المنفذ، عناوين IP مختلفة

StackOverflow https://stackoverflow.com/questions/703051

  •  22-08-2019
  •  | 
  •  

سؤال

لقد واجهت مشكلة.أنا جديد قليلاً في WCF لذا فإن أي مساعدة ستكون محل تقدير كبير.

هذا هو الكود الخاص بي:

public static void StartHosts()
    {
        try
        {
            // Create a new host
            ServiceHost host = new ServiceHost(typeof(ServerTasks));

            List<IPAddress> ips = new List<IPAddress>(Dns.GetHostAddresses(Dns.GetHostName()));
            if (IPAddress.Loopback != null)
                ips.Add(IPAddress.Loopback);

            ips.RemoveAll(i => i.AddressFamily != AddressFamily.InterNetwork);

            foreach (var ip in ips)
            {
                string uri = string.Empty;

                // Formulate the uri for this host
                uri = string.Format(
                    "net.tcp://{0}:{1}/ServerTasks",
                    ip.ToString(),
                    ServerSettings.Instance.TCPListeningPort
                );


                // Add the endpoint binding
                host.AddServiceEndpoint(
                    typeof(ServerTasks),
                    new NetTcpBinding(SecurityMode.Transport) { TransferMode = TransferMode.Streamed },
                    uri
                );

            }



            // Add the meta data publishing
            var smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (smb == null)
                smb = new ServiceMetadataBehavior();

            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            host.Description.Behaviors.Add(smb);

            host.AddServiceEndpoint(
                ServiceMetadataBehavior.MexContractName,
                MetadataExchangeBindings.CreateMexTcpBinding(),
                "net.tcp://localhost/ServerTasks/mex"
            );

            // Run the host
            host.Open();
        }
        catch (Exception exc)
        {
            DebugLogger.WriteException(exc);
        }
    }

تم طرح استثناء على السطر:"المضيف.فتح ()؛"

الاستثناء هو:

System.InvalidOperationExceptionيوجد تسجيل بالفعل لـ URI 'net.tcp://192.168.1.45:4329/ServerTasks'.

ما أحاول القيام به هو الارتباط بجميع عناوين الشبكة الموجودة على الجهاز حتى تتمكن تطبيقات العميل من الوصول إلى الخدمة من أي شبكة يرونها عليها.عندما أقوم بتشغيل هذا الرمز، فإنه يجد ويحاول إعداد ربط لحوالي 5 عناوين IP مختلفة، بما في ذلك 127.0.0.1.

192.168.1.45 هو عنوان IP الثاني الذي يحاول الارتباط به.عند النقطة التي يطرح فيها الاستثناء أستطيع أن أرى (باستخدام netstat) أن البرنامج مرتبط بأول عنوان IP في القائمة على المنفذ 4329.لا يوجد أي شيء مرتبط بالمنفذ 4329 على العنوان المذكور في الاستثناء.

آسف ليس هناك الكثير من التفاصيل، أردت أن أعطي تدوينة موجزة.إذا كان أي شخص يحتاج إلى أي معلومات أخرى سأكون سعيدًا بتقديمها.

ملحوظة:لقد حاولت تعيين PortSharingEnabled على القيمة true بالنسبة لـ NetTcpBinding الذي يتم إنشاؤه داخل حلقة foreach، ولكن ما زلت أواجه نفس الخطأ.

أي مساعدة أو نصيحة سيكون موضع تقدير كبير!

شكرًا

هل كانت مفيدة؟

المحلول

شكرا للمعلومات كورازا!

لقد اكتشفت كيفية تحقيق ذلك.كنت أفعل هذا بطريقة خاطئة.

كان هدفي النهائي هو جعل الخدمة تستمع إلى كل عنوان IP متوفر على الجهاز.إن محاولة الارتباط بكل عنوان على حدة هي الطريقة الخاطئة للقيام بذلك.

وبدلاً من ذلك، كنت بحاجة فقط إلى ربط الخدمة بالجهاز اسم المضيف (وليس "المضيف المحلي") ويستمع WCF تلقائيًا إلى جميع المحولات.

إليك الكود المصحح:

public static void StartHosts()
    {
        try
        {
            // Formulate the uri for this host
            string uri = string.Format(
                "net.tcp://{0}:{1}/ServerTasks",
                Dns.GetHostName(),
                ServerSettings.Instance.TCPListeningPort
            );

            // Create a new host
            ServiceHost host = new ServiceHost(typeof(ServerTasks), new Uri(uri));

            // Add the endpoint binding
            host.AddServiceEndpoint(
                typeof(ServerTasks),
                new NetTcpBinding(SecurityMode.Transport) 
                        { 
                            TransferMode = TransferMode.Streamed
                        },
                uri
            );

            // Add the meta data publishing
            var smb = host.Description.Behaviors.Find<ServiceMetadataBehavior>();
            if (smb == null)
                smb = new ServiceMetadataBehavior();

            smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
            host.Description.Behaviors.Add(smb);

            host.AddServiceEndpoint(
                ServiceMetadataBehavior.MexContractName,
                MetadataExchangeBindings.CreateMexTcpBinding(),
                "net.tcp://localhost/ServerTasks/mex"
            );

            // Run the host
            host.Open();
        }
        catch (Exception exc)
        {
            DebugLogger.WriteException(exc);
        }
    }

نصائح أخرى

ميل،

على الرغم من أنني لم أجرب هذا من قبل بنفسي، فإليك بعض العينات التي سمعتها من قبل لإلقاء نظرة عليها.قد ترغب في إنشاء كائن الربط الخاص بك أولاً ثم إضافة نفس المثيل إلى طريقة AddServiceEndpoint، مجرد فكرة حتى لا تقوم بإنشاء روابط جديدة في كل مرة كما أتذكر أنني قرأت في مكان ما أن netTCPBindings يجب أن تكون علاقة 1:1 مع العنوان (على الرغم من أنك تستخدم عناوين مختلفة).

لا أعتقد أنه يجب عليك القلق بشأن مشاركة المنافذ حيث أنك تفتح منافذ متعددة.

فيما يلي نموذج لما قد ترغب في تحقيقه باستخدام منافذ متعددة.

http://www.aspfree.com/c/a/Windows-Scripting/WCF-and-Bindings/2/

فيما يلي نموذج جيد لاستخدام مشاركة المنفذ على NetTcpBinding.

http://blogs.msdn.com/drnick/archive/2006/08/08/690333.aspx

-براين

يبدو أنني تأخرت قليلا :).ولكن على أية حال - هناك طريقة بسيطة جدًا لجعل Wcf يستمع إلى جميع واجهات الشبكة المتاحة "net.tcp://0.0.0.0:8523/WCFTestService".

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top