使用同一winform中的NetTcpBinding调用WCF服务

时间:2018-04-25 20:51:40

标签: c# iis iis-express nettcpbinding servicehost

嘿,所有我都有以下代码,允许我为WCF服务启动临时Web服务,而无需自行调整IIS Express。

但是,下面的代码可以很好地如果我在另一个winform中获取数据。将相同的代码复制到WCF服务winform会导致在尝试发送患者索引号时冻结。

类代码(Class1.cs):

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;

/*
    HOW TO HOST THE WCF SERVICE IN THIS LIBRARY IN ANOTHER PROJECT
    You will need to do the following things: 
    1)    Add a Host project to your solution
        a.    Right click on your solution
        b.    Select Add
        c.    Select New Project
        d.    Choose an appropriate Host project type (e.g. Console Application)
    2)    Add a new source file to your Host project
        a.    Right click on your Host project
        b.    Select Add
        c.    Select New Item
        d.    Select "Code File"
    3)    Paste the contents of the "MyServiceHost" class below into the new Code File
    4)    Add an "Application Configuration File" to your Host project
        a.    Right click on your Host project
        b.    Select Add
        c.    Select New Item
        d.    Select "Application Configuration File"
    5)    Paste the contents of the App.Config below that defines your service endoints into the new Config File
    6)    Add the code that will host, start and stop the service
        a.    Call MyServiceHost.StartService() to start the service and MyServiceHost.EndService() to end the service
    7)    Add a Reference to System.ServiceModel.dll
        a.    Right click on your Host Project
        b.    Select "Add Reference"
        c.    Select "System.ServiceModel.dll"
    8)    Add a Reference from your Host project to your Service Library project
        a.    Right click on your Host Project
        b.    Select "Add Reference"
        c.    Select the "Projects" tab
    9)    Set the Host project as the "StartUp" project for the solution
        a.    Right click on your Host Project
        b.    Select "Set as StartUp Project"

    ################# START MyServiceHost.cs #################

    using System;
    using System.ServiceModel;

    // A WCF service consists of a contract (defined below), 
    // a class which implements that interface, and configuration 
    // entries that specify behaviors and endpoints associated with 
    // that implementation (see <system.serviceModel> in your application
    // configuration file).

    internal class MyServiceHost
    {
        internal static ServiceHost myServiceHost = null;

        internal static void StartService()
        {
            //Consider putting the baseAddress in the configuration system
            //and getting it here with AppSettings
            Uri baseAddress = new Uri("http://localhost:8080/service1");

            //Instantiate new ServiceHost 
            myServiceHost = new ServiceHost(typeof(TestService.service1), baseAddress);

            //Open myServiceHost
            myServiceHost.Open();
        }

        internal static void StopService()
        {
            //Call StopService from your shutdown logic (i.e. dispose method)
            if (myServiceHost.State != CommunicationState.Closed)
                myServiceHost.Close();
        }
    }

    ################# END MyServiceHost.cs #################
    ################# START App.config or Web.config #################

    <system.serviceModel>
    <services>
         <service name="TestService.service1">
           <endpoint contract="TestService.IService1" binding="wsHttpBinding"/>
         </service>
       </services>
    </system.serviceModel>

    ################# END App.config or Web.config #################

*/
namespace TestService
{
    // You have created a class library to define and implement your WCF service.
    // You will need to add a reference to this library from another project and add 
    // the code to that project to host the service as described below.  Another way
    // to create and host a WCF service is by using the Add New Item, WCF Service 
    // template within an existing project such as a Console Application or a Windows 
    // Application.

    [ServiceContract()]
    public interface IService1
    {
        [OperationContract]
        Patient GetPatient(Int32 index);

        [OperationContract]
        void SetPatient(Int32 index, Patient patient);
    }

    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class PatientService : IService1
    {
        Patient[] pat = null;

        public PatientService()
        {
            pat = new Patient[3];

            pat[0] = new Patient();
            pat[0].FirstName = "Bob";
            pat[0].LastName = "Chandler";

            pat[1] = new Patient();
            pat[1].FirstName = "Joe";
            pat[1].LastName = "Klink";

            pat[2] = new Patient();
            pat[2].FirstName = "Sally";
            pat[2].LastName = "Wilson";
        }

        public Patient GetPatient(Int32 index)
        {
            if (index <= pat.GetUpperBound(0) && index > -1)
                return pat[index];
            else
                return new Patient();
        }

        public void SetPatient(Int32 index, Patient patient)
        {
            if (index <= pat.GetUpperBound(0) && index > -1)
                pat[index] = patient;
        }
    }

    [DataContract]
    public class Patient
    {
        string firstName;
        string lastName;

        [DataMember]
        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }

        [DataMember]
        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }
    }
}

服务代码(Form1.cs):

using System;
using System.Windows.Forms;
using System.ServiceModel;

namespace TestService
{
    public partial class Form1 : Form
    {
        bool serviceStarted = false;
        ServiceHost myServiceHost = null;
        NetTcpBinding binding;
        Uri baseAddress = new Uri("net.tcp://localhost:2202/PatientService");

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (serviceStarted)
            {
                myServiceHost.Close();
                serviceStarted = false;
                button1.Text = "Start Service";
            }
            else
            {
                binding = new NetTcpBinding();
                myServiceHost = new ServiceHost(typeof(PatientService), baseAddress);
                myServiceHost.AddServiceEndpoint(typeof(IService1), binding, baseAddress);

                myServiceHost.Open();

                serviceStarted = true;
                button1.Text = "Stop Service";    
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            IService1 patientSvc = null;
            EndpointAddress address = new EndpointAddress(baseAddress);
            ChannelFactory<IService1> factory = new ChannelFactory<IService1>(binding, address);
            patientSvc = factory.CreateChannel();

            Patient patient = patientSvc.GetPatient(Convert.ToInt32(textBox1.Text));

            if (patient != null)
            {
                textBox2.Text = patient.FirstName;
                textBox3.Text = patient.LastName;
            }
        }
    }

    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

enter image description here

此处的代码行:

Patient patient = patientSvc.GetPatient(Convert.ToInt32(textBox1.Text));

是冻结的地方。同样,这与其他winform中的代码相同,可以运行。只是在服务中使用它本身并不是出于某种原因而以同样的方式工作?

它给出的错误是:

  

System.TimeoutException:&#39;发送到net.tcp:// localhost:2202 / PatientService的请求操作未在配置的超时(00:01:00)内收到回复。分配给此操作的时间可能是较长超时的一部分。这可能是因为服务仍在处理操作,或者因为服务无法发送回复消息。请考虑增加操作超时(通过将频道/代理转换为IContextChannel并设置OperationTimeout属性)并确保该服务能够连接到客户端。&#39;

任何人都知道如何让它发挥作用?

这是另一个winform代码:

using System;
using System.Windows.Forms;
using System.ServiceModel;
using TestService;

namespace TestClient
{
    public partial class Form1 : Form
    {
        IService1 patientSvc = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            EndpointAddress address = new EndpointAddress(new Uri("net.tcp://localhost:2202/PatientService"));
            NetTcpBinding binding = new NetTcpBinding();
            ChannelFactory<IService1> factory = new ChannelFactory<IService1>(binding, address);
            patientSvc = factory.CreateChannel();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Patient patient = patientSvc.GetPatient(Convert.ToInt32(textBox1.Text));

            if (patient != null)
            {
                textBox2.Text = patient.FirstName;
                textBox3.Text = patient.LastName;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Patient patient = new Patient();
            patient.FirstName = textBox2.Text;
            patient.LastName = textBox3.Text;

            patientSvc.SetPatient(Convert.ToInt32(textBox1.Text), patient);
        }
    }
}

TestClient代码(Program.cs):

using System;
using System.Windows.Forms;

namespace TestClient
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

enter image description here

1 个答案:

答案 0 :(得分:0)

知道了!感谢@Eser提示:)

<?php 
if($this->Flash->render('alert')){
    echo $this->Flash->render('alert');
}
?>