
参考资料地址:http://www.cnblogs.com/server126/archive/2011/08/11/2134942.html
代码实现:
WCF宿主(服务端)
IServices.cs 服务契约(其实就是接口)
namespace Host
{
[ServiceContract(SessionMode = SessionMode.Required, CallbackContract = typeof(ICallBackServices))]
public interface IServices
{
/// <summary>
/// 注册客户端信息
/// </summary>
[OperationContract(IsOneWay = false)]
void Register();
}
/// <summary>
/// 回调接口
/// </summary>
public interface ICallBackServices
{
/// <summary>
/// 服务像客户端发送信息(异步)
/// </summary>
/// <param name="Message"></param>
[OperationContract(IsOneWay = true)]
void SendMessage(string Message); /// <summary>
/// 服务端像客户端(异步)发送图片流
/// </summary>
/// <param name="messageEntity"></param>
[OperationContract(IsOneWay = true)]
void SendPicStream(MessageEntity messageEntity);
}
}
MessageEntity.cs 消息实体类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Runtime.Serialization; namespace WcfDuplex
{
/// <summary>
/// 消息实体类
/// </summary>
[DataContract]
public class MessageEntity
{
[DataMember]
public string Content { get; set; } [DataMember]
public byte[] PicStream { get; set; }
}
}
Services.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Configuration; namespace Host
{
/// <summary>
/// 实例使用Single,共享一个
/// 并发使用Mutiple, 支持多线程访问(一定要加锁)
/// </summary>
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class Services : IServices
{
public static readonly string SendMessageType = ConfigurationManager.ConnectionStrings["SendMessageType"].ToString();
private static readonly object InstObj = new object();//单一实例
//public static List<ICallBackServices> RegList = null;
public static Dictionary<string, ICallBackServices> DicHost = null; //记录机器名称
public static Dictionary<string, ICallBackServices> DicHostSess = null;//记录Sessionid
public Services()
{
//RegList = new List<ICallBackServices>();
DicHost = new Dictionary<string, ICallBackServices>();
DicHostSess = new Dictionary<string, ICallBackServices>();
}
#region IServices 成员 public void Register()
{
ICallBackServices client = OperationContext.Current.GetCallbackChannel<ICallBackServices>();
string sessionid = OperationContext.Current.SessionId;//获取当前机器Sessionid--------------------------如果多个客户端在同一台机器,就使用此信息。
string ClientHostName = OperationContext.Current.Channel.RemoteAddress.Uri.Host;//获取当前机器名称-----多个客户端不在同一台机器上,就使用此信息。
OperationContext.Current.Channel.Closing += new EventHandler(Channel_Closing);//注册客户端关闭触发事件
if (SendMessageType.ToUpper() == "SESSIONID")
{
DicHostSess.Add(sessionid, client);//添加
}
else
{
DicHost.Add(ClientHostName, client); //添加
}
//RegList.Add(client);//添加
}
void Channel_Closing(object sender, EventArgs e)
{
lock (InstObj)//加锁,处理并发
{
//if (RegList != null && RegList.Count > 0)
// RegList.Remove((ICallBackServices)sender);
if (SendMessageType.ToUpper() == "SESSIONID")
{
if (DicHostSess != null && DicHostSess.Count > )
{
foreach (var d in DicHostSess)
{
if (d.Value == (ICallBackServices)sender)//删除此关闭的客户端信息
{
DicHostSess.Remove(d.Key);
break;
}
}
}
}
else
{
if (DicHost != null && DicHost.Count > ) //同上
{
foreach (var d in DicHost)
{
if (d.Value == (ICallBackServices)sender)
{
DicHost.Remove(d.Key);
break;
}
}
}
}
}
}
#endregion
}
}
服务端
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;
using System.Threading;
using WcfDuplex;
using System.IO; namespace Host
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private static readonly object InstObj = new object();
private static bool isval = true;
private void Form1_Load(object sender, EventArgs e)
{
ServiceHost host = new ServiceHost(typeof(Services));
host.Open();
this.Text = "wcf服务启动成功!"; #region 初始化ListBox
Thread thread = new Thread(new ThreadStart(delegate ///监听所有客户端连接,并添加到ListBox控件里
{
lock (InstObj)//加锁
{
while (true)
{ if (Services.SendMessageType.ToUpper() == "SESSIONID")
{
if (Services.DicHostSess != null || Services.DicHostSess.Count > )
{
this.Invoke(new MethodInvoker(delegate { this.listBox1.Items.Clear(); }));
foreach (var l in Services.DicHostSess)
{
this.Invoke(new MethodInvoker(delegate
{
this.listBox1.Items.Add(l.Key);
}));
}
}
}
else
{
if (Services.DicHost != null || Services.DicHost.Count > )
{
this.Invoke(new MethodInvoker(delegate { this.listBox1.Items.Clear(); }));
foreach (var l in Services.DicHost)
{
this.Invoke(new MethodInvoker(delegate
{
this.listBox1.Items.Add(l.Key);
}));
}
}
}
Thread.Sleep( * );
}
}
}));
thread.IsBackground = true;
thread.Start();
#endregion
} #region 推送
int i = ;
private void button1_Click(object sender, EventArgs e)
{
i++;
if (Services.DicHostSess == null || Services.DicHostSess.Count > )
{
if (this.listBox1.SelectedItem != null)
{
if (this.listBox1.SelectedItem.ToString() != "")
{
foreach (var d in Services.DicHostSess)
{
if (d.Key == this.listBox1.SelectedItem.ToString())
{
//d.Value.SendMessage(string.Format("Time: {0} message {1}", DateTime.Now, textBox1.Text.Trim()));
MessageEntity messageEntity = new MessageEntity();
if (i<)
{
string picPath = @"D:\download\wcf推送与广播\Host\Img\" + i + ".jpg";
messageEntity.PicStream = ImageDatabytes(picPath);
d.Value.SendPicStream(messageEntity);
}
}
}
}
}
else
{
MessageBox.Show("请选择要推送给哪台客户端");
i--;
return;
}
}
if (Services.DicHost != null || Services.DicHost.Count > )
{
if (this.listBox1.SelectedItem != null)
{
if (this.listBox1.SelectedItem.ToString() != "")
{
foreach (var d in Services.DicHost)
{
if (d.Key == this.listBox1.SelectedItem.ToString())
{
//d.Value.SendMessage(string.Format("Time: {0} message {1}", DateTime.Now, textBox1.Text.Trim()));
MessageEntity messageEntity = new MessageEntity();
if (i < )
{
string picPath = @"D:\download\wcf推送与广播\Host\Img\" + i + ".jpg";
messageEntity.PicStream = ImageDatabytes(picPath);
d.Value.SendPicStream(messageEntity);
}
}
}
}
}
else
{
MessageBox.Show("请选择要推送给哪台客户端");
i--;
return;
}
}
}
#endregion #region 广播方式
private void button2_Click(object sender, EventArgs e)
{
if (Services.SendMessageType.ToUpper() == "SESSIONID")//类型
{
foreach (var d in Services.DicHostSess)
{
d.Value.SendMessage(this.textBox1.Text);
}
}
else
{
foreach (var d in Services.DicHost)
{
d.Value.SendMessage(this.textBox1.Text);
}
}
}
#endregion #region 根据图片路径将图片转换为二进制流
/// <summary>
/// 根据图片路径将图片转换为二进制流
/// </summary>
/// <param name="FilePath"></param>
/// <returns></returns>
public static byte[] ImageDatabytes(string FilePath)
{
if (!File.Exists(FilePath))
return null;
Bitmap myBitmap = new Bitmap(Image.FromFile(FilePath)); using (MemoryStream curImageStream = new MemoryStream())
{
myBitmap.Save(curImageStream, System.Drawing.Imaging.ImageFormat.Png);
curImageStream.Flush(); byte[] bmpBytes = curImageStream.ToArray();
//如果转字符串的话
//string BmpStr = Convert.ToBase64String(bmpBytes);
return bmpBytes;
}
}
#endregion }
}
WinFormClient.cs 客户端
客户端Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.ServiceModel; namespace WinFormClient
{ public partial class FormClient : Form
{
public FormClient()
{
InitializeComponent();
this.Text = "当前客户端编号为:"+DateTime.Now.ToString("yyyyMMddHHmmss");
try
{
Console.WriteLine("create object...");
CallBack back = new CallBack();
InstanceContext context = new InstanceContext(back);
ServiceReference1.ServicesClient client = new ServiceReference1.ServicesClient(context);
Console.WriteLine("regist.....");
back.showPic += new CallBack.ShowPic(ShowPicMethod);
client.Register();
Console.WriteLine("aucceeded");
//this.ReceivePic.Image = back.Pic;
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
} public void ShowPicMethod(Bitmap bitmap)
{
this.ReceivePic.Image = bitmap;
}
} public class CallBack : ServiceReference1.IServicesCallback
{
public delegate void ShowPic(Bitmap bitmap);
public event ShowPic showPic; #region IServicesCallback 成员
public void SendMessage(string Message)
{
Console.WriteLine("[ClientTime{0:HHmmss}]Service Broadcast:{1}", DateTime.Now, Message);
} public void SendPicStream(ServiceReference1.MessageEntity messageEntity)
{
this.showPic(GetImage(messageEntity.PicStream));
}
#endregion #region 将图片二进制流转换为图片
public static Bitmap GetImage(byte[] ImageDatas)
{
try
{
//如果是字符串的话
//byte[] resultBytes = Convert.FromBase64String(ImageDatas);
using (MemoryStream ImageMS = new MemoryStream())
{
ImageMS.Write(ImageDatas, , ImageDatas.Length);
Bitmap resultBitmap = new Bitmap(ImageMS);
return resultBitmap;
}
}
catch
{
return null;
}
}
#endregion
}
}
Demo下载地址:http://files.cnblogs.com/files/wgx0428/wcf%E6%8E%A8%E9%80%81%E4%B8%8E%E5%B9%BF%E6%92%AD.zip