参考资料地址: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:\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         #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

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

使用用WCF中的双工(Duplex)模式将广告图片推送到每个Winform客户端机子上相关推荐

  1. 原型模式-广告邮件推送

    1. 广告邮件推送 现在大部分系统都有「发送邮件」的功能,系统可以通过邮件的方式给客户发送一些通知.消息提醒.广告推送的邮件. 其中,「广告邮件」比较特殊,它的邮件内容都是一样的,唯一不同的目标邮箱, ...

  2. 直播平台开发中解决iOS 14 兼容问题和静默推送

    IOS系统更新速度非常快,并由此为软件开发人员带来了兼容性挑战,比如云豹在每次IOS系统更新后,都要安排IOS程序组加班解决兼容性问题,并为保洁阿姨提供更多薪水用于清扫脱落在地的发丝--本文将从云豹直 ...

  3. 在网页广告栏中经常看到左右来回移动的广告图片。请使用html+js实现一个左右移动的图片效果。图片自选。

    在网页广告栏中经常看到左右来回移动的广告图片.请使用html+js实现一个左右移动的图片效果.图片自选. <!DOCTYPE html> <html><head>& ...

  4. 在WCF中实现双工通信(转载)

    首先声明此文章是转载博客园蒋老师之作:http://www.cnblogs.com/artech/archive/2007/03/02/661969.html 双工(Duplex)模式的消息交互方式体 ...

  5. [转载]我的WCF之旅(3):在WCF中实现双工通信

    http://www.cnblogs.com/artech/archive/2007/03/02/661969.html 双工(Duplex)模式的消息交换方式体现在消息交换过程中,参与的双方均可以向 ...

  6. 苹果暗黑模式_苹果正式推送iOS13.4、iPadOS更新,微信安卓版暗黑模式来了,手机淘宝出现弹窗Bug,柔宇第二代折叠屏手机发布...

    大家好 今天是3月25日 一起来看看今天的科技大新闻 苹果正式推送iOS13.4.iPadOS 更新支持触控板操作 (新浪科技)北京时间3月25日凌晨,苹果公司正式推送了iOS 13.4.iPadOS ...

  7. 记:.net中海关终端节点报文加签与推送

    keyInfoName 海关cer文件名, certificate 海关cer内容 DxpMsg dxpMsg = new DxpMsg(); XmlSerializerNamespaces name ...

  8. 干货 | Reactive模式在Trip.com消息推送平台上的实践

    作者简介 KevinTen,携程后端开发工程师,关注Reactive和RPC领域,深度参与开源社区,对Reactive技术有浓厚兴趣. Pin,携程技术专家,Apache Dubbo贡献者,关注RPC ...

  9. 物联网学习 第4讲 中移OneNET HTTP推送服务接入

    物联网开发 第4讲 中移OneNET HTTP推送服务接入 在使用OneNET平台时,如果我们自己开发应用,基本上会有获取设备的上下线信息以及设备上传的数据点的需求. 为了满足上述的需求,我们有以下两 ...

最新文章

  1. 腾讯微博快速有效增加广播转播量的方法与技巧
  2. Java 内存分配——Thinking in Java 4th 读书笔记
  3. java bean转string_Json、JavaBean、String等互转
  4. 年薪 50w+ 的程序员,是这样写代码的?
  5. C++deque双端队列
  6. [C#]写自己的类库
  7. c语言程序原版PDF,正式版C语言程序设计.pdf
  8. 现在单片机编程语言是c吗,单片机编程用什么语言 哪个适合新手
  9. 伍德里奇计量经济学第六版第七章计算机答案,伍德里奇计量经济学第六版答案Appendix-E...
  10. reviewboard mysql_Linux ReviewBoard安装与配置
  11. 计算机windows安全如何打开,windows安全中心如何关闭
  12. 用PS调出二次元风格水彩漫画风景图片
  13. 【数据结构】选择排序
  14. win10修改用户名_大神帮您win10系统用户文件夹改名的修复方法
  15. POJ3322(bfs+状态限制)
  16. html提取excel指定单元格数据,怎样从很多的表格中提取指定单元格数据
  17. A ArrayLink for JavaME
  18. AD转换中【参考电压】的作用
  19. Excel删除区域内的空白格
  20. linux最大文件名,linux和windows文件名长度限制

热门文章

  1. java 静态扫描_静态代码扫描工具 – (八)- 扫描Java项目
  2. java jdk运行_java运行机制、Jdk版本及Java环境变量
  3. Flask 和 Google App Engine 部署模型服务
  4. colordialog通过哪属性取其颜色_IT兄弟连 HTML5教程 CSS3揭秘 CSS常见的样式属性和值1...
  5. 苹果手机关闭自动更新_苹果手机会quot;偷钱quot;的2个功能,越早关闭越好,不然经常无故被扣钱...
  6. Long Short-Term Memory Over Tree Structures
  7. 黑莓发布企业服务SWS 兼容Android和iOS设备
  8. python 网络维护_python学习之网络基础
  9. CYQ.Data V4.5.5 版本发布[顺带开源Emit编写的快速反射转实体类FastToT类]
  10. 使用TensorFlow 来实现一个简单的验证码识别过程