zoukankan      html  css  js  c++  java
  • 使用用WCF中的双工(Duplex)模式将广告图片推送到每个Winform客户端机子上

    参考资料地址:http://www.cnblogs.com/server126/archive/2011/08/11/2134942.html

    代码实现:

      WCF宿主(服务端)

    IServices.cs 服务契约(其实就是接口)

     1 namespace Host
     2 {
     3     [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ICallBackServices))]
     4     public interface IServices
     5     {
     6        /// <summary>
     7        /// 注册客户端信息
     8        /// </summary>
     9         [OperationContract(IsOneWay = false)]
    10         void Register();
    11     }
    12     /// <summary>
    13     ///  回调接口
    14     /// </summary>
    15     public interface ICallBackServices
    16     {
    17         /// <summary>
    18         /// 服务像客户端发送信息(异步)
    19         /// </summary>
    20         /// <param name="Message"></param>
    21         [OperationContract(IsOneWay = true)]
    22         void SendMessage(string Message);
    23 
    24         /// <summary>
    25         /// 服务端像客户端(异步)发送图片流
    26         /// </summary>
    27         /// <param name="messageEntity"></param>
    28         [OperationContract(IsOneWay = true)]
    29         void SendPicStream(MessageEntity messageEntity);
    30     }
    31 } 
    View Code

    MessageEntity.cs 消息实体类

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Web;
     5 using System.Runtime.Serialization;
     6 
     7 namespace WcfDuplex
     8 {
     9     /// <summary>
    10     /// 消息实体类
    11     /// </summary>
    12     [DataContract]
    13     public class MessageEntity
    14     {
    15         [DataMember]
    16         public string Content { get; set; }
    17 
    18         [DataMember]
    19         public byte[] PicStream { get; set; }
    20     }
    21 }

    Services.cs

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.ServiceModel;
     6 using System.Configuration;
     7 
     8 namespace Host
     9 {
    10     /// <summary>
    11     ///  实例使用Single,共享一个
    12     ///  并发使用Mutiple, 支持多线程访问(一定要加锁)
    13     /// </summary>
    14     [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
    15     public class Services : IServices
    16     {
    17         public static readonly string SendMessageType = ConfigurationManager.ConnectionStrings["SendMessageType"].ToString();
    18         private static readonly object InstObj = new object();//单一实例
    19         //public static List<ICallBackServices> RegList = null;
    20         public static Dictionary<string, ICallBackServices> DicHost = null; //记录机器名称
    21         public static Dictionary<string, ICallBackServices> DicHostSess = null;//记录Sessionid
    22         public Services()
    23         {
    24             //RegList = new List<ICallBackServices>();
    25             DicHost = new Dictionary<string, ICallBackServices>();
    26             DicHostSess = new Dictionary<string, ICallBackServices>();
    27         }
    28         #region IServices 成员
    29 
    30         public void Register()
    31         {
    32             ICallBackServices client = OperationContext.Current.GetCallbackChannel<ICallBackServices>();
    33             string sessionid = OperationContext.Current.SessionId;//获取当前机器Sessionid--------------------------如果多个客户端在同一台机器,就使用此信息。
    34             string ClientHostName = OperationContext.Current.Channel.RemoteAddress.Uri.Host;//获取当前机器名称-----多个客户端不在同一台机器上,就使用此信息。
    35             OperationContext.Current.Channel.Closing += new EventHandler(Channel_Closing);//注册客户端关闭触发事件
    36             if (SendMessageType.ToUpper() == "SESSIONID")
    37             {
    38                 DicHostSess.Add(sessionid, client);//添加
    39             }
    40             else
    41             {
    42                 DicHost.Add(ClientHostName, client); //添加
    43             }
    44             //RegList.Add(client);//添加
    45         }
    46         void Channel_Closing(object sender, EventArgs e)
    47         {
    48             lock (InstObj)//加锁,处理并发
    49             {
    50                 //if (RegList != null && RegList.Count > 0)
    51                 //    RegList.Remove((ICallBackServices)sender); 
    52                 if (SendMessageType.ToUpper() == "SESSIONID")
    53                 {
    54                     if (DicHostSess != null && DicHostSess.Count > 0)
    55                     {
    56                         foreach (var d in DicHostSess)
    57                         {
    58                             if (d.Value == (ICallBackServices)sender)//删除此关闭的客户端信息
    59                             {
    60                                 DicHostSess.Remove(d.Key);
    61                                 break;
    62                             }
    63                         }
    64                     }
    65                 }
    66                 else
    67                 {
    68                     if (DicHost != null && DicHost.Count > 0) //同上
    69                     {
    70                         foreach (var d in DicHost)
    71                         {
    72                             if (d.Value == (ICallBackServices)sender)
    73                             {
    74                                 DicHost.Remove(d.Key);
    75                                 break;
    76                             }
    77                         }
    78                     }
    79                 }
    80             }
    81         }
    82         #endregion
    83     }
    84 } 
    View Code

    服务端

    Form1.cs

      1 using System;
      2 using System.Collections.Generic;
      3 using System.ComponentModel;
      4 using System.Data;
      5 using System.Drawing;
      6 using System.Linq;
      7 using System.Text;
      8 using System.Windows.Forms;
      9 using System.ServiceModel;
     10 using System.Threading;
     11 using WcfDuplex;
     12 using System.IO;
     13 
     14 namespace Host
     15 {
     16     public partial class Form1 : Form
     17     {
     18         public Form1()
     19         {
     20             InitializeComponent();
     21         }
     22         private static readonly object InstObj = new object();
     23         private static bool isval = true;
     24         private void Form1_Load(object sender, EventArgs e)
     25         {
     26             ServiceHost host = new ServiceHost(typeof(Services));
     27             host.Open();
     28             this.Text = "wcf服务启动成功!";
     29 
     30             #region 初始化ListBox
     31             Thread thread = new Thread(new ThreadStart(delegate   ///监听所有客户端连接,并添加到ListBox控件里
     32             {
     33                 lock (InstObj)//加锁
     34                 {
     35                     while (true)
     36                     {
     37 
     38                         if (Services.SendMessageType.ToUpper() == "SESSIONID")
     39                         {
     40                             if (Services.DicHostSess != null || Services.DicHostSess.Count > 0)
     41                             {
     42                                 this.Invoke(new MethodInvoker(delegate { this.listBox1.Items.Clear(); }));
     43                                 foreach (var l in Services.DicHostSess)
     44                                 {
     45                                     this.Invoke(new MethodInvoker(delegate
     46                                     {
     47                                         this.listBox1.Items.Add(l.Key);
     48                                     }));
     49                                 }
     50                             }
     51                         }
     52                         else
     53                         {
     54                             if (Services.DicHost != null || Services.DicHost.Count > 0)
     55                             {
     56                                 this.Invoke(new MethodInvoker(delegate { this.listBox1.Items.Clear(); }));
     57                                 foreach (var l in Services.DicHost)
     58                                 {
     59                                     this.Invoke(new MethodInvoker(delegate
     60                                     {
     61                                         this.listBox1.Items.Add(l.Key);
     62                                     }));
     63                                 }
     64                             }
     65                         }
     66                         Thread.Sleep(1000 * 10);
     67                     }
     68                 }
     69             }));
     70             thread.IsBackground = true;
     71             thread.Start();
     72             #endregion
     73         }
     74 
     75         #region 推送
     76         int i = 0;
     77         private void button1_Click(object sender, EventArgs e)
     78         {
     79             i++;
     80             if (Services.DicHostSess == null || Services.DicHostSess.Count > 0)
     81             {
     82                 if (this.listBox1.SelectedItem != null)
     83                 {
     84                     if (this.listBox1.SelectedItem.ToString() != "")
     85                     {
     86                         foreach (var d in Services.DicHostSess)
     87                         {
     88                             if (d.Key == this.listBox1.SelectedItem.ToString())
     89                             {
     90                                 //d.Value.SendMessage(string.Format("Time: {0} message {1}", DateTime.Now, textBox1.Text.Trim()));
     91                                 MessageEntity messageEntity = new MessageEntity();
     92                                 if (i<4)
     93                                 {
     94                                     string picPath = @"D:downloadwcf推送与广播HostImg" + i + ".jpg";
     95                                     messageEntity.PicStream = ImageDatabytes(picPath);
     96                                     d.Value.SendPicStream(messageEntity);
     97                                 }
     98                             }
     99                         }
    100                     }
    101                 }
    102                 else 
    103                 { 
    104                     MessageBox.Show("请选择要推送给哪台客户端");
    105                     i--;
    106                     return; 
    107                 }
    108             }
    109             if (Services.DicHost != null || Services.DicHost.Count > 0)
    110             {
    111                 if (this.listBox1.SelectedItem != null)
    112                 {
    113                     if (this.listBox1.SelectedItem.ToString() != "")
    114                     {
    115                         foreach (var d in Services.DicHost)
    116                         {
    117                             if (d.Key == this.listBox1.SelectedItem.ToString())
    118                             {
    119                                 //d.Value.SendMessage(string.Format("Time: {0} message {1}", DateTime.Now, textBox1.Text.Trim()));
    120                                 MessageEntity messageEntity = new MessageEntity();
    121                                 if (i < 4)
    122                                 {
    123                                     string picPath = @"D:downloadwcf推送与广播HostImg" + i + ".jpg";
    124                                     messageEntity.PicStream = ImageDatabytes(picPath);
    125                                     d.Value.SendPicStream(messageEntity);
    126                                 }
    127                             }
    128                         }
    129                     }
    130                 }
    131                 else 
    132                 { 
    133                     MessageBox.Show("请选择要推送给哪台客户端");
    134                     i--;
    135                     return; 
    136                 }
    137             }
    138         } 
    139         #endregion
    140         
    141         #region 广播方式
    142         private void button2_Click(object sender, EventArgs e)
    143         {
    144             if (Services.SendMessageType.ToUpper() == "SESSIONID")//类型
    145             {
    146                 foreach (var d in Services.DicHostSess)
    147                 {
    148                     d.Value.SendMessage(this.textBox1.Text);
    149                 }
    150             }
    151             else
    152             {
    153                 foreach (var d in Services.DicHost)
    154                 {
    155                     d.Value.SendMessage(this.textBox1.Text);
    156                 }
    157             }
    158         } 
    159         #endregion
    160 
    161         #region 根据图片路径将图片转换为二进制流
    162         /// <summary>
    163         /// 根据图片路径将图片转换为二进制流
    164         /// </summary>
    165         /// <param name="FilePath"></param>
    166         /// <returns></returns>
    167         public static byte[] ImageDatabytes(string FilePath)
    168         {
    169             if (!File.Exists(FilePath))
    170                 return null;
    171             Bitmap myBitmap = new Bitmap(Image.FromFile(FilePath));
    172 
    173             using (MemoryStream curImageStream = new MemoryStream())
    174             {
    175                 myBitmap.Save(curImageStream, System.Drawing.Imaging.ImageFormat.Png);
    176                 curImageStream.Flush();
    177 
    178                 byte[] bmpBytes = curImageStream.ToArray();
    179                 //如果转字符串的话
    180                 //string BmpStr = Convert.ToBase64String(bmpBytes);
    181                 return bmpBytes;
    182             }
    183         } 
    184         #endregion
    185 
    186     }
    187 }
    View Code

    WinFormClient.cs 客户端

    客户端Form1.cs

     1 using System;
     2 using System.Collections.Generic;
     3 using System.ComponentModel;
     4 using System.Data;
     5 using System.Drawing;
     6 using System.Linq;
     7 using System.Text;
     8 using System.Windows.Forms;
     9 using System.IO;
    10 using System.ServiceModel;
    11 
    12 namespace WinFormClient
    13 {
    14     
    15 
    16     public partial class FormClient : Form
    17     {
    18         public FormClient()
    19         {
    20             InitializeComponent();
    21             this.Text = "当前客户端编号为:"+DateTime.Now.ToString("yyyyMMddHHmmss");
    22             try
    23             {
    24                 Console.WriteLine("create object...");
    25                 CallBack back = new CallBack();
    26                 InstanceContext context = new InstanceContext(back);
    27                 ServiceReference1.ServicesClient client = new ServiceReference1.ServicesClient(context);
    28                 Console.WriteLine("regist.....");
    29                 back.showPic += new CallBack.ShowPic(ShowPicMethod);
    30                 client.Register();
    31                 Console.WriteLine("aucceeded");
    32                 //this.ReceivePic.Image = back.Pic;
    33             }
    34             catch (Exception ex) { Console.WriteLine(ex.Message); }
    35         }
    36 
    37         public void ShowPicMethod(Bitmap bitmap)
    38         {
    39             this.ReceivePic.Image = bitmap;
    40         }
    41     }
    42 
    43     public class CallBack : ServiceReference1.IServicesCallback
    44     {
    45         public delegate void ShowPic(Bitmap bitmap);
    46         public event ShowPic showPic;
    47 
    48         #region IServicesCallback 成员
    49         public void SendMessage(string Message)
    50         {
    51             Console.WriteLine("[ClientTime{0:HHmmss}]Service Broadcast:{1}", DateTime.Now, Message);
    52         }
    53 
    54         public void SendPicStream(ServiceReference1.MessageEntity messageEntity)
    55         {
    56             this.showPic(GetImage(messageEntity.PicStream));
    57         }
    58         #endregion
    59 
    60         #region 将图片二进制流转换为图片
    61         public static Bitmap GetImage(byte[] ImageDatas)
    62         {
    63             try
    64             {
    65                 //如果是字符串的话
    66                 //byte[] resultBytes = Convert.FromBase64String(ImageDatas);
    67                 using (MemoryStream ImageMS = new MemoryStream())
    68                 {
    69                     ImageMS.Write(ImageDatas, 0, ImageDatas.Length);
    70                     Bitmap resultBitmap = new Bitmap(ImageMS);
    71                     return resultBitmap;
    72                 }
    73             }
    74             catch
    75             {
    76                 return null;
    77             }
    78         }
    79         #endregion
    80     }
    81 }
    View Code

     Demo下载地址:http://files.cnblogs.com/files/wgx0428/wcf%E6%8E%A8%E9%80%81%E4%B8%8E%E5%B9%BF%E6%92%AD.zip

  • 相关阅读:
    也谈谈关于WEB的感想
    spring boot,https,双向ssl认证
    Spring Cloud Gateway(二)
    Spring Cloud Gateway(一)
    .Net Web Service 自定义返回值命名
    随便记一下,C#并行环境操作Winform的代码段
    随便记一下,解决Windows Server 2012无法远程登录的方法
    记录C#控件DataGridView绑定BindingList无法排序问题(转)
    记录SQL Server 2019链接Oracle 11g R2的过程
    Json CPP 中文支持与入门示例
  • 原文地址:https://www.cnblogs.com/wgx0428/p/3539568.html
Copyright © 2011-2022 走看看