WCF ตั้งชื่อไปป์มินิมอลตัวอย่าง


90

ฉันกำลังมองหาตัวอย่างเล็ก ๆ น้อย ๆ ของ WCF Named Pipes (ฉันคาดว่าจะมีแอปพลิเคชั่นขั้นต่ำสองตัวเซิร์ฟเวอร์และไคลเอนต์ซึ่งสามารถสื่อสารผ่านท่อที่มีชื่อ)

Microsoft มีบทความแนะนำการเริ่มต้นใช้งานที่อธิบายถึง WCF ผ่าน HTTP และฉันกำลังมองหาสิ่งที่คล้ายกันเกี่ยวกับ WCF และไปป์ที่มีชื่อ

ฉันพบโพสต์หลายรายการในอินเทอร์เน็ต แต่เป็น "ขั้นสูง" เล็กน้อย ฉันต้องการบางสิ่งบางอย่างที่น้อยที่สุดเป็นเพียงฟังก์ชันที่จำเป็นเท่านั้นจึงจะสามารถเพิ่มรหัสและทำให้แอปพลิเคชันทำงาน

ฉันจะแทนที่มันเพื่อใช้ไปป์ที่มีชื่อได้อย่างไร

<endpoint address="http://localhost:8000/ServiceModelSamples/Service/CalculatorService"
    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalculator"
    contract="ICalculator" name="WSHttpBinding_ICalculator">
    <identity>
        <userPrincipalName value="OlegPc\Oleg" />
    </identity>
</endpoint>

ฉันจะแทนที่มันเพื่อใช้ไปป์ที่มีชื่อได้อย่างไร

// Step 1 of the address configuration procedure: Create a URI to serve as the base address.
Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");

// Step 2 of the hosting procedure: Create ServiceHost
ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);

try
{
    // Step 3 of the hosting procedure: Add a service endpoint.
    selfHost.AddServiceEndpoint(
        typeof(ICalculator),
        new WSHttpBinding(),
        "CalculatorService");

    // Step 4 of the hosting procedure: Enable metadata exchange.
    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
    smb.HttpGetEnabled = true;
    selfHost.Description.Behaviors.Add(smb);

    // Step 5 of the hosting procedure: Start (and then stop) the service.
    selfHost.Open();
    Console.WriteLine("The service is ready.");
    Console.WriteLine("Press <ENTER> to terminate service.");
    Console.WriteLine();
    Console.ReadLine();

    // Close the ServiceHostBase to shutdown the service.
    selfHost.Close();
}
catch (CommunicationException ce)
{
    Console.WriteLine("An exception occurred: {0}", ce.Message);
    selfHost.Abort();
}

ฉันจะสร้างไคลเอนต์เพื่อใช้ไปป์ที่มีชื่อได้อย่างไร


1
คุณได้ดูstackoverflow.com/questions/184878/…หรือยัง
Christoph

คำตอบ:


80

ฉันเพิ่งพบบทช่วยสอนเล็ก ๆ น้อย ๆ ที่ยอดเยี่ยมนี้ ลิงก์เสีย ( เวอร์ชันแคช )

ฉันยังทำตามบทช่วยสอนของ Microsoft ซึ่งดี แต่ฉันต้องการท่อเท่านั้นเช่นกัน

อย่างที่คุณเห็นคุณไม่จำเป็นต้องมีไฟล์คอนฟิกูเรชันและของยุ่ง ๆ

เขาใช้ทั้ง HTTP และไปป์ เพียงลบบรรทัดโค้ดทั้งหมดที่เกี่ยวข้องกับ HTTP คุณจะได้รับตัวอย่างไปป์ที่แท้จริง


2
ขอบคุณ! นอกจากนี้เมื่อพยายามสร้างบริการที่ใช้ web.config สำหรับการกำหนดค่าแทนการกำหนดค่าแบบฮาร์ดโค้ดโปรดดูตัวอย่างของ Microsoft นี้: msdn.microsoft.com/en-us/library/ms752253.aspx
Nullius

3
ลิงก์ใช้งานไม่ได้มีการสอนที่อื่นหรือไม่
user1069816

ใช้เวลาสักพักเพื่อพยายามหาสาเหตุว่าทำไม "ท่อจึงสิ้นสุดลง" นี่คือวิธีแก้ปัญหาของฉันหวังว่าจะช่วยได้: stackoverflow.com/a/49075797/385273
Ben

62

ลองทำตามนี้

นี่คือส่วนบริการ

[ServiceContract]
public interface IService
{
    [OperationContract]
    void  HelloWorld();
}

public class Service : IService
{
    public void HelloWorld()
    {
        //Hello World
    }
}

นี่คือพร็อกซี

public class ServiceProxy : ClientBase<IService>
{
    public ServiceProxy()
        : base(new ServiceEndpoint(ContractDescription.GetContract(typeof(IService)),
            new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/MyAppNameThatNobodyElseWillUse/helloservice")))
    {

    }
    public void InvokeHelloWorld()
    {
        Channel.HelloWorld();
    }
}

และนี่คือส่วนบริการโฮสติ้ง

var serviceHost = new ServiceHost
        (typeof(Service), new Uri[] { new Uri("net.pipe://localhost/MyAppNameThatNobodyElseWillUse") });
    serviceHost.AddServiceEndpoint(typeof(IService), new NetNamedPipeBinding(), "helloservice");
    serviceHost.Open();

    Console.WriteLine("Service started. Available in following endpoints");
    foreach (var serviceEndpoint in serviceHost.Description.Endpoints)
    {
        Console.WriteLine(serviceEndpoint.ListenUri.AbsoluteUri);
    }

สิ่งนี้อาจใช้งานได้ แต่ไม่ยืดหยุ่นเท่ากับการแก้ไขไฟล์ app.config สำหรับไคลเอนต์และเซิร์ฟเวอร์ ...
Alan S

9
ดีเนื่องจากการเปิดเผยรายละเอียดแอปพลิเคชันผ่านไฟล์ app.config มักไม่ต้องการ
Frank Hileman

14
นี่เป็นตัวอย่างที่ยอดเยี่ยมอย่างไรก็ตามอย่าใช้ที่อยู่ฐานของ net.pipe: // localhost / หากคุณทำและเครื่องมีโปรแกรมอื่นที่ใช้ net.pipe: // localhost / ServiceHost จะแสดงข้อยกเว้นเมื่อคุณเปิด ให้ใช้สิ่งที่ไม่เหมือนใครแทนเช่น net.pipe: // localhost / MyAppNameThatNobodyElseWillUse หวังว่านี่จะช่วยประหยัดเวลาและความยุ่งยากให้กับคนอื่นได้บ้าง!
Doug Clutter

วิธีนี้ใช้ได้ผลดี โดยเฉพาะอย่างยิ่งสำหรับปลายทางภายในที่ไม่จำเป็นต้องมีการอ้างอิงบริการใน config เพียงแค่รักษาสัญญา - เพียงแค่คำจำกัดความของอินเทอร์เฟซ - ในชุดประกอบของตัวเองและบางทีอาจเป็นที่อยู่ใน config ไม่มีแนวโน้มที่การผูกจะเปลี่ยนไป
Rob Von Nesselrode

2
ฉันต้องการเพิ่ม/helloserviceที่ส่วนท้ายของที่อยู่ปลายทางในพร็อกซี
Mormegil

14

ดูตัวอย่าง Echo ที่เรียบง่ายมากของฉัน: มันถูกออกแบบมาเพื่อใช้การสื่อสาร HTTP พื้นฐาน แต่สามารถแก้ไขได้อย่างง่ายดายเพื่อใช้ไปป์ที่มีชื่อโดยการแก้ไขไฟล์app.configสำหรับไคลเอนต์และเซิร์ฟเวอร์ ทำการเปลี่ยนแปลงต่อไปนี้:

แก้ไขไฟล์app.configของเซิร์ฟเวอร์ลบหรือแสดงความคิดเห็นรายการ http baseAddressและเพิ่มรายการbaseAddressใหม่สำหรับไปป์ที่มีชื่อ (เรียกว่าnet.pipe ) นอกจากนี้หากคุณไม่ต้องการใช้ HTTP สำหรับโปรโตคอลการสื่อสารตรวจสอบให้แน่ใจว่าserviceMetadataและserviceDebugถูกแสดงความคิดเห็นหรือลบออก:

<configuration>
    <system.serviceModel>
        <services>
            <service name="com.aschneider.examples.wcf.services.EchoService">
                <host>
                    <baseAddresses>
                        <add baseAddress="net.pipe://localhost/EchoService"/>
                    </baseAddresses>
                </host>
            </service>
        </services>
        <behaviors>
            <serviceBehaviors></serviceBehaviors>
        </behaviors>
    </system.serviceModel>
</configuration>

แก้ไขไฟล์app.configของไคลเอ็นต์เพื่อให้basicHttpBindingแสดงความคิดเห็นหรือลบออกและเพิ่มรายการnetNamedPipeBinding คุณจะต้องเปลี่ยนรายการปลายทางเพื่อใช้ไปป์:

<configuration>
    <system.serviceModel>
        <bindings>
            <netNamedPipeBinding>
                <binding name="NetNamedPipeBinding_IEchoService"/>
            </netNamedPipeBinding>
        </bindings>
        <client>
            <endpoint address              = "net.pipe://localhost/EchoService"
                      binding              = "netNamedPipeBinding"
                      bindingConfiguration = "NetNamedPipeBinding_IEchoService"
                      contract             = "EchoServiceReference.IEchoService"
                      name                 = "NetNamedPipeBinding_IEchoService"/>
        </client>
    </system.serviceModel>
</configuration>

ตัวอย่างข้างต้นจะทำงานกับไปป์ที่มีชื่อเท่านั้น แต่ไม่มีอะไรหยุดคุณจากการใช้หลายโปรโตคอลเพื่อเรียกใช้บริการของคุณ AFAIK คุณควรจะมีเซิร์ฟเวอร์ที่เรียกใช้บริการโดยใช้ทั้งไพพ์ที่มีชื่อและ HTTP (รวมถึงโปรโตคอลอื่น ๆ )

นอกจากนี้การเชื่อมโยงในไฟล์app.configของไคลเอ็นต์นั้นง่ายมาก มีพารามิเตอร์ต่างๆมากมายที่คุณสามารถปรับเปลี่ยนได้นอกเหนือจากการระบุbaseAddress ...


5
ตอนนี้ลิงค์ตายแล้ว
Chris Weber

2

ฉันสร้างตัวอย่างง่ายๆนี้จากผลการค้นหาต่างๆบนอินเทอร์เน็ต

public static ServiceHost CreateServiceHost(Type serviceInterface, Type implementation)
{
  //Create base address
  string baseAddress = "net.pipe://localhost/MyService";

  ServiceHost serviceHost = new ServiceHost(implementation, new Uri(baseAddress));

  //Net named pipe
  NetNamedPipeBinding binding = new NetNamedPipeBinding { MaxReceivedMessageSize = 2147483647 };
  serviceHost.AddServiceEndpoint(serviceInterface, binding, baseAddress);

  //MEX - Meta data exchange
  ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
  serviceHost.Description.Behaviors.Add(behavior);
  serviceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexNamedPipeBinding(), baseAddress + "/mex/");

  return serviceHost;
}

การใช้ URI ข้างต้นฉันสามารถเพิ่มข้อมูลอ้างอิงในไคลเอนต์ของฉันไปยังบริการเว็บได้


-2

ฉันพบว่าไซต์นี้มีประโยชน์จริงๆและโครงการตัวอย่างทำงานโดยไม่ต้องปรับแต่งใด ๆ : https://dotnet-experience.blogspot.com/2012/02/inter-process-duplex-communication-with.html

อย่าลืมเปิดใช้งานการสนับสนุน Named Pipe ในคุณสมบัติของ Windows บทความนี้มีภาพหน้าจอที่ดีสำหรับเอฟเฟกต์นั้นในคำตอบด้านบน: WCF Named Pipe ในบริการ Windows โดยใช้ App.Config

โครงการที่อ้างถึงในโซลูชันที่ยอมรับไม่ทำงานตามที่เป็นอยู่บนพีซีของฉัน ฉันลองแก้ไขบางอย่างใน app.config แต่ยังคงได้รับข้อยกเว้นต่อไปนี้:

System.InvalidOperationException: 'Service' WpfWcfNamedPipeBinding.NamedPipeBindingService 'ไม่มีจุดสิ้นสุดของแอปพลิเคชัน (ไม่ใช่โครงสร้างพื้นฐาน) เป็นศูนย์ อาจเป็นเพราะไม่พบไฟล์คอนฟิกูเรชันสำหรับแอปพลิเคชันของคุณหรือเนื่องจากไม่พบองค์ประกอบบริการที่ตรงกับชื่อบริการในไฟล์คอนฟิกูเรชันหรือเนื่องจากไม่มีการกำหนดจุดสิ้นสุดในองค์ประกอบบริการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.