сделать экземпляр класса в C # / WCF? - PullRequest
0 голосов
/ 09 апреля 2011

Извините, что снова опубликовал тот же вопрос, но с первого раза все не так. :)

Вот код серверного приложения, которое может принимать соединение и отправлять сообщения клиенту.

Как видите, у меня есть " class Form1: Form " для графического интерфейса пользователя и " class ServerWCallbackImpl: IServerWithCallback " с функциями сервера.

Проблема в том, что эти классы не могут общаться, то есть я не могу вызвать функцию сервера из события формы, такого как buttonClick, и не могу изменить что-либо внутри формы, скажем, TextBox1.Text + = .. ., из функции сервера.

Может быть, кто-нибудь может объяснить, как должен выглядеть код, чтобы он работал?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;

namespace server
{


[ServiceContract(Namespace = "server", CallbackContract = typeof(IDataOutputCallback), SessionMode = SessionMode.Required)]


public interface IServerWithCallback           ///// what comes from the client to the server.
{
    [OperationContract(IsOneWay = true)]
    void StartConnection(string clientName);

    [OperationContract(IsOneWay = true)]
    void Message_Cleint2Server(string msg);
}


public interface IDataOutputCallback          ///// what goes from the sertver, to the client.
{
    [OperationContract(IsOneWay = true)]
    void AcceptConnection();

    [OperationContract(IsOneWay = true)]
    void Message_Server2Client(string msg);
}


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        private void Form1_Load(object sender, EventArgs e)     /// once the form loads, create and open a new ServiceEndpoint.
        {
              ServiceHost duplex = new ServiceHost(typeof(ServerWCallbackImpl));
              duplex.AddServiceEndpoint(typeof(IServerWithCallback), new NetTcpBinding(), "net.tcp://localhost:9080/service");
              duplex.Open();
              this.Text = "SERVER *on-line*";
        }

        private void buttonSendMsg_Click(object sender, EventArgs e)
        {
            /// callback.Message_Server2Client(textBox2.Text);
            /// The name 'Message_Server2Client' does not exist in the current context :(
        }

    }



        class ServerWCallbackImpl : IServerWithCallback /// NEED TO SOMEHOW MERGE THIS ONE WITH THE FORM1 CLASS
        {


            IDataOutputCallback callback = OperationContext.Current.GetCallbackChannel<IDataOutputCallback>();


            public void StartConnection(string name)
            {
                /// TextBox1.text += name + " has connected!";
                /// 'TextBox1' does not exist in the current context :(
                /// can't reach form1 components. :/
                MessageBox.Show( name + " has connected!");
                Message2Client("Welcome, "+name+"!");
            }


            public void Message_Cleint2Server(string msg)
            {
                /// TextBox1.text += msg;
                /// 'TextBox1' does not exist in the current context :(
                /// can't reach form1 components. :/
            }


            public void Message2Client(string msg)
            {
                callback.Message_Server2Client(msg);
            }


        }

}

1 Ответ

1 голос
/ 09 апреля 2011

Время жизни дуплексной переменной ограничено методом Form1_Load.Это означает, что ваш хост прекратит работу после завершения метода.Чтобы поддерживать работающий хост, объявите дуплексную переменную вне метода и просто создайте ее экземпляр в методе.

Примерно так:

public partial class Form1 : Form {
    //Declare the variable in the class, not the method body
    private ServiceHost duplex;

    public Form1() {
        InitializeComponent();
    }

    // once the form loads open a new ServiceEndpoint. 
    private void Form1_Load(object sender, EventArgs e) {
          duplex = new ServiceHost(typeof(ServerWCallbackImpl));
          duplex.AddServiceEndpoint(typeof(IServerWithCallback), new NetTcpBinding(), "net.tcp://localhost:9080/service");
          duplex.Open();
          this.Text = "SERVER *on-line*";
    }

    private void buttonSendMsg_Click(object sender, EventArgs e) {
        /// callback.Message_Server2Client(textBox2.Text);
        /// The name 'Message_Server2Client' does not exist in the current context :(
    }

}

EDIT1:

Если создан экземпляр ServiceHostс типом, как в вашем примере, экземпляр этого типа будет создан для каждого соединения.Вы можете установить время жизни экземпляра для сеанса, вызова или соединения, как я полагаю.Я не уверен, как этот объект будет иметь доступ к вашей форме, хотя.Однако, если вы сами создадите экземпляр класса ServerWCallbackImpl и передадите ссылку на хост, этот экземпляр будет использован.

public partial class Form1 : Form {
    //Declare the variable in the class, not the method body
    private ServiceHost duplex;
    private ServerWithCallbackImpl localInstance;

    public Form1() {
        InitializeComponent();
    }

   private void Form1_Load(object sender, EventArgs e) {
      localInstance = new ServerWithCallbackImpl();
      NetTcpBinding binding = new NetTcpBinding ();
      duplex = new ServiceHost(localInstance, new Uri[] { new Uri("net.tcp://localhost:9080") });
      duplex .AddServiceEndpoint(typeof(IServerWithCallback), binding, "service");
      duplex .Open();
      this.Text = "SERVER *on-line*";
   }
 }

Затем объект ServerWithCallbackImpl должен будет отслеживать своих клиентов.Чтобы сервер обновил графический интерфейс, вы можете передать ссылку на форму в качестве параметра в конструктор ServerWithCallbackImpl.Взгляните на шаблон публикации / подписчика , чтобы получить более глубокое понимание обратных вызовов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...