C# C带远程处理的简单聊天应用程序:客户端表单未更新

C# C带远程处理的简单聊天应用程序:客户端表单未更新,c#,chat,remoting,C#,Chat,Remoting,我正在尝试在C Visual Studio中使用远程处理创建一个简单的聊天应用程序。 我的问题是,客户机用端口向服务器发送一个连接请求,服务器接收该请求,用端口在字典中注册客户机,然后向客户机发回一个问候消息以进行测试。我可以在客户端控制台中打印来自服务器的消息,但是表单不会更新 代码如下: 在客户端和服务器的共享库中,我有两个接口,一个用于服务器的服务: namespace ChatApplication { public interface IServerServices {

我正在尝试在C Visual Studio中使用远程处理创建一个简单的聊天应用程序。 我的问题是,客户机用端口向服务器发送一个连接请求,服务器接收该请求,用端口在字典中注册客户机,然后向客户机发回一个问候消息以进行测试。我可以在客户端控制台中打印来自服务器的消息,但是表单不会更新

代码如下:

在客户端和服务器的共享库中,我有两个接口,一个用于服务器的服务:

namespace ChatApplication
{
    public interface IServerServices
    {
        void sendMessage(string client, string msg);

        void register(string client, int port);

    }
}
另一个用于客户服务:

namespace ChatApplication
{
    public interface IClientServices
    {
        void receiveMsg(string s);
    }
}
在服务器中,我有:

namespace ChatApplication
{
    public class ChatServer
    {
        static void Main(string[] args)
        {
            TcpChannel channel = new TcpChannel(8086);
            ChannelServices.RegisterChannel(channel, false);
            RemotingConfiguration.RegisterWellKnownServiceType(
                typeof(ServerServices),
                "RemoteObject",
                WellKnownObjectMode.Singleton);        
            System.Console.ReadLine();
        }
    }
}
以及实现服务器服务的类:

namespace ChatApplication
{
    public class ServerServices : MarshalByRefObject, IServerServices
    {
        private Dictionary<string, IClientServices> clients =
            new Dictionary<string, IClientServices>();

        public void register(string client, int port)
        {
            Console.WriteLine("Registered client: " + client + " on port: " + port);
        IClientServices cli = (IClientServices )Activator.GetObject(
            typeof(IClientServices),
            "tcp://localhost:" + port + "/RemoteClient");

        clients.Add(client, cli);
        cli.receiveMsg("Hello client " + client); //Just to test the form on the client
    }

}
实现客户端服务的类:

namespace ChatApplication
{
    static class ChatClient
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Form1 form = new Form1();
            Application.Run(form);
        }
    }
}
namespace ChatApplication
{
    public class ClientServices : MarshalByRefObject, IClientServices 
    {

        public static Form1 myForm;

        public ClientServices ()
        {
        }

        public void receiveMsg(string s)
        {
            myForm.addMsg(s);
        }

    }
}
namespace ChatApplication
{
    public partial class Form1 : Form
    {

        TcpChannel newch;

        public Form1()
        {
            InitializeComponent();
        }

        public void addMsg(string s)
        {
            Console.WriteLine("received msg " + s);
            session.Text += s + "\r\n";
        }

        public void connectButton_Click(object sender, EventArgs e)
        {
            int port = Int32.Parse(portText.Text);
            newch = new TcpChannel(port);
            ChannelServices.RegisterChannel(newch, false);
            ClientServices.myForm = this;
            RemotingConfiguration.RegisterWellKnownServiceType(
                typeof(ClientServices),
                "RemoteClient",
                WellKnownObjectMode.Singleton);

            IServerServices serverInstance = (IServerServices)Activator.GetObject(
            typeof(IServerServices),
            "tcp://localhost:8086/RemoteObject");

            serverInstance.register(nickname.Text, port);
        }
    }
}
最后是客户的申请表:

namespace ChatApplication
{
    static class ChatClient
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Form1 form = new Form1();
            Application.Run(form);
        }
    }
}
namespace ChatApplication
{
    public class ClientServices : MarshalByRefObject, IClientServices 
    {

        public static Form1 myForm;

        public ClientServices ()
        {
        }

        public void receiveMsg(string s)
        {
            myForm.addMsg(s);
        }

    }
}
namespace ChatApplication
{
    public partial class Form1 : Form
    {

        TcpChannel newch;

        public Form1()
        {
            InitializeComponent();
        }

        public void addMsg(string s)
        {
            Console.WriteLine("received msg " + s);
            session.Text += s + "\r\n";
        }

        public void connectButton_Click(object sender, EventArgs e)
        {
            int port = Int32.Parse(portText.Text);
            newch = new TcpChannel(port);
            ChannelServices.RegisterChannel(newch, false);
            ClientServices.myForm = this;
            RemotingConfiguration.RegisterWellKnownServiceType(
                typeof(ClientServices),
                "RemoteClient",
                WellKnownObjectMode.Singleton);

            IServerServices serverInstance = (IServerServices)Activator.GetObject(
            typeof(IServerServices),
            "tcp://localhost:8086/RemoteObject");

            serverInstance.register(nickname.Text, port);
        }
    }
}
问题是我在客户端控制台中看到文本Hello client+。。。 但是客户端表单的元素会话不更新,客户端崩溃。实现客户机服务的类具有字段myForm has static,因为我不知道发布具有字段的远程对象的其他方法,所以我采用了这种方法,我想它是可行的,只是表单没有更新。我做错了什么


对于所有的代码,我很抱歉,但我想通过这种方式您可以看到这里发生了什么。

暗中摸索:这可能是一个并发问题。尝试序列化对客户端UI的访问,以避免访问重叠。因此,当您访问UI时,您是否正在编组到UI线程上?粗略地检查一下您的UI代码,我认为这不是问题所在。WriteLine应该为您这样做,但在您发布错误消息之前,没有人能提供很大帮助。

它是如何崩溃的?有什么有意义的错误吗?就像提到跨线程操作一样?客户端只是冻结了,但是如果我在这行中放置一个断点:serverInstance.registernickname.Text,porto;我得到一个SocketException:没有建立连接,因为目标拒绝了它。我把信息翻译成英语了使用远程处理的具体原因是什么?有点过时了,现在有很多更好的选择。大学作业嗯。。。一所非常古老的大学?