重温WCF之群聊天程序(十)

完成的效果图:

服务器端代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;

namespace SendMessageHostConsoleApplication
{
    [ServiceContract(SessionMode=SessionMode.Required,CallbackContract=typeof(ICallback))]
    public interface IService
    {
        /// <summary>
        /// 启动会话
        /// </summary>
        [OperationContract(IsOneWay=true,IsInitiating=true,IsTerminating=false)]
        void Begin();

        /// <summary>
        /// 客户端调用服务器端发送消息
        /// </summary>
        /// <param name="nick"></param>
        /// <param name="msg"></param>
        /// <param name="sendTime"></param>
        [OperationContract(IsOneWay = true)]
        void SendMessage(string nick,string msg,DateTime sendTime);

        /// <summary>
        /// 终止会话
        /// </summary>
        [OperationContract(IsOneWay=true,IsInitiating=false,IsTerminating=true)]
        void End();

    }

    public interface ICallback
    {
        /// <summary>
        /// 服务器端调用客户端发送消息
        /// </summary>
        /// <param name="nick"></param>
        /// <param name="msg"></param>
        /// <param name="sendTime"></param>
        [OperationContract(IsOneWay=true)]
        void SendToClients(string nick,string msg,DateTime sendTime);
    }

    [ServiceBehavior(IncludeExceptionDetailInFaults=true,InstanceContextMode=InstanceContextMode.PerSession)]
    public class MyService : IService
    {
        public static Dictionary<string, ICallback> ClientCallBacks = new Dictionary<string, ICallback>();
        public void Begin()
        {
            string sessionId = OperationContext.Current.SessionId;
            ICallback cb = OperationContext.Current.GetCallbackChannel<ICallback>();
            MyService.ClientCallBacks[sessionId] = cb;
        }

        public void SendMessage(string nick, string msg, DateTime sendTime)
        {
            foreach (ICallback  c in MyService.ClientCallBacks.Values)
            {
                if (c != null)
                {
                    c.SendToClients(nick, msg, sendTime);
                }
            }
        }

        public void End()
        {
            string sessionId = OperationContext.Current.SessionId;
            if (MyService.ClientCallBacks.ContainsKey(sessionId))
            {
                MyService.ClientCallBacks.Remove(sessionId);
            }
        }
    }
    public class Program
    {
        public static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(MyService)))
            {
                NetTcpBinding bingding = new NetTcpBinding();
                bingding.Security.Mode = SecurityMode.None;//不需要安全模式
                host.AddServiceEndpoint(typeof(IService), bingding, "net.tcp://127.0.0.1:8868/channel");

                ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
                behavior.HttpGetEnabled = true;
                behavior.HttpGetUrl = new Uri("http://127.0.0.1:8888/WSDL"); //httpGetUrl客户端引用的地址
                host.Description.Behaviors.Add(behavior);
                host.Opened += delegate
                {
                    Console.WriteLine("服务已启动");
                    Console.ReadKey();
                };
                host.Open();
            }
        }
    }
}

客户端调用代码:

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

namespace SendMessageClientWindowsFormsApplication
{
    
    public partial class Form1 : Form
    {
        private WS.ServiceClient client = null;
        public Form1()
        {
            InitializeComponent();
            MyCallback callback = new MyCallback();
            callback.MessageReceived += callback_MessageReceived;
            var instanceContext = new InstanceContext(callback);
            client = new WS.ServiceClient(instanceContext);
            client.Begin();
            this.FormClosed += Form1_FormClosed;
        }

        void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            client.End();
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
     
            client.SendMessage(this.txtNick.Text, this.txtSendMsg.Text, DateTime.Now);
        }

        void callback_MessageReceived(object sender, CallbackRecEventArgs e)
        {
            ListViewItem item = new ListViewItem();
            Font font = new System.Drawing.Font(new FontFamily("宋体"), 12,FontStyle.Bold);
            item.Font = font;
            item.ForeColor = Color.Blue;
            if (e.Nick == this.txtNick.Text)
            {
                item.ForeColor = Color.Green;
            }
            item.Text = e.Nick + "        " + e.SendTime+"
";
            listView1.Items.Add(item);
            listView1.Items.Add(e.Message);
            this.txtSendMsg.Text = "";
        }
    }

    public class MyCallback : WS.IServiceCallback
    {
        public void SendToClients(string nick, string msg, DateTime sendTime)
        {
            if (this.MessageReceived != null)
            {
                CallbackRecEventArgs arg = new CallbackRecEventArgs(nick, msg, sendTime);
                this.MessageReceived(this, arg);
            }
        }

        public event EventHandler<CallbackRecEventArgs> MessageReceived;
    }

    public class CallbackRecEventArgs : EventArgs
    {
        private string _Nick, _Msg;
        private DateTime _time;

        public CallbackRecEventArgs(string nk, string m, DateTime t)
        {
            _Nick = nk;
            _Msg = m;
            _time = t;
        }

        public string Nick
        {
            get { return _Nick; }
        }

        public string Message
        {
            get { return _Msg; }
        }

        public DateTime SendTime
        {
            get { return _time; }
        }
    }

}
原文地址:https://www.cnblogs.com/yxlblogs/p/3785965.html