博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用用WCF中的双工(Duplex)模式将广告图片推送到每个Winform客户端机子上
阅读量:5116 次
发布时间:2019-06-13

本文共 13841 字,大约阅读时间需要 46 分钟。

参考资料地址:

代码实现:

  WCF宿主(服务端)

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

1 namespace Host 2 { 3     [ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ICallBackServices))] 4     public interface IServices 5     { 6        ///  7        /// 注册客户端信息 8        ///  9         [OperationContract(IsOneWay = false)]10         void Register();11     }12     /// 13     ///  回调接口14     /// 15     public interface ICallBackServices16     {17         /// 18         /// 服务像客户端发送信息(异步)19         /// 20         /// 21         [OperationContract(IsOneWay = true)]22         void SendMessage(string Message);23 24         /// 25         /// 服务端像客户端(异步)发送图片流26         /// 27         /// 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     /// 10     /// 消息实体类11     /// 12     [DataContract]13     public class MessageEntity14     {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     /// 11     ///  实例使用Single,共享一个12     ///  并发使用Mutiple, 支持多线程访问(一定要加锁)13     /// 14     [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]15     public class Services : IServices16     {17         public static readonly string SendMessageType = ConfigurationManager.ConnectionStrings["SendMessageType"].ToString();18         private static readonly object InstObj = new object();//单一实例19         //public static List
RegList = null;20 public static Dictionary
DicHost = null; //记录机器名称21 public static Dictionary
DicHostSess = null;//记录Sessionid22 public Services()23 {24 //RegList = new List
();25 DicHost = new Dictionary
();26 DicHostSess = new Dictionary
();27 }28 #region IServices 成员29 30 public void Register()31 {32 ICallBackServices client = OperationContext.Current.GetCallbackChannel
();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 else41 {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 else67 {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 #endregion83 }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:\download\wcf推送与广播\Host\Img\" + 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:\download\wcf推送与广播\Host\Img\" + 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         #endregion140         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             else152             {153                 foreach (var d in Services.DicHost)154                 {155                     d.Value.SendMessage(this.textBox1.Text);156                 }157             }158         } 159         #endregion160 161         #region 根据图片路径将图片转换为二进制流162         /// 163         /// 根据图片路径将图片转换为二进制流164         /// 165         /// 166         /// 
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 #endregion185 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 WinFormClient13 {14     15 16     public partial class FormClient : Form17     {18         public FormClient()19         {20             InitializeComponent();21             this.Text = "当前客户端编号为:"+DateTime.Now.ToString("yyyyMMddHHmmss");22             try23             {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.IServicesCallback44     {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         #endregion59 60         #region 将图片二进制流转换为图片61         public static Bitmap GetImage(byte[] ImageDatas)62         {63             try64             {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             catch75             {76                 return null;77             }78         }79         #endregion80     }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

转载于:https://www.cnblogs.com/wgx0428/p/3539568.html

你可能感兴趣的文章
Mysql 索引优化 - 1
查看>>
LeetCode(3) || Median of Two Sorted Arrays
查看>>
大话文本检测经典模型:EAST
查看>>
待整理
查看>>
一次动态sql查询订单数据的设计
查看>>
C# 类(10) 抽象类.
查看>>
Vue_(组件通讯)子组件向父组件传值
查看>>
jvm参数
查看>>
我对前端MVC的理解
查看>>
Silverlight实用窍门系列:19.Silverlight调用webservice上传多个文件【附带源码实例】...
查看>>
2016.3.31考试心得
查看>>
mmap和MappedByteBuffer
查看>>
Linux的基本操作
查看>>
转-求解最大连续子数组的算法
查看>>
对数器的使用
查看>>
【ASP.NET】演绎GridView基本操作事件
查看>>
ubuntu无法解析主机错误与解决的方法
查看>>
尚学堂Java面试题整理
查看>>
MySQL表的四种分区类型
查看>>
[BZOJ 3489] A simple rmq problem 【可持久化树套树】
查看>>