重温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("宋体"), ,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+"\r\n";
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; }
}
} }
重温WCF之群聊天程序(十)的更多相关文章
- Socket聊天程序——初始设计
写在前面: 可能是临近期末了,各种课程设计接踵而来,最近在csdn上看到2个一样问答(问题A,问题B),那就是编写一个基于socket的聊天程序,正好最近刚用socket做了一些事,出于兴趣,自己抽了 ...
- Comet实现的网页聊天程序
“上一篇”介绍了我在c/s程序中用了那些技术,如今只谈c/s不谈b/s那未免out了,势必要写一写b/s的程序与大家共勉. 回忆做技术这些年,06年每天盯着“天轰穿”的视频不亦乐乎,估计那是一代程序员 ...
- WCF技术剖析之二十八:自己动手获取元数据[附源代码下载]
原文:WCF技术剖析之二十八:自己动手获取元数据[附源代码下载] 元数据的发布方式决定了元数据的获取行为,WCF服务元数据架构体系通过ServiceMetadataBehavior实现了基于WS-ME ...
- WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇]
原文:WCF技术剖析之二十六:如何导出WCF服务的元数据(Metadata)[实现篇] 元数据的导出就是实现从ServiceEndpoint对象向MetadataSet对象转换的过程,在WCF元数据框 ...
- WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇]
原文:WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[中篇] 在[上篇]中,我们分别站在消息交换和编程的角度介绍了SOAP Fault和FaultException异常.在服务执行过 ...
- WCF技术剖析之二十: 服务在WCF体系中是如何被描述的?
原文:WCF技术剖析之二十: 服务在WCF体系中是如何被描述的? 任何一个程序都需要运行于一个确定的进程中,进程是一个容器,其中包含程序实例运行所需的资源.同理,一个WCF服务的监听与执行同样需要通过 ...
- Socket编程之聊天程序 - 模拟Fins/ModBus协议通信过程
设备控制软件编程涉及到的基本通信方式主要有TCP/IP与串口,用到的数据通信协议有Fins与ModBus. 更高级别的通信如.net中的Remoting与WCF在进行C/S架构软件开发时会采用. 本篇 ...
- 基于UDP协议的控制台聊天程序(c++版)
本博客由Rcchio原创,转载请告知作者 ------------------------------------------------------------------------------- ...
- java Socket多线程聊天程序
参考JAVA 通过 Socket 实现 TCP 编程 参考java Socket多线程聊天程序(适合初学者) 以J2SDK-1.3为例,Socket和ServerSocket类库位于java.net包 ...
随机推荐
- ubuntu 出现g++ : Depends: g++-4.8 (>= 4.8.2-5~) but it is not going to be installed
Ubuntu 你可以安装搜狗输入法也可以使用sunpingyin,看个人爱好. 唯一要注意的是,不能把系统的更新关了,否则会出现一大堆的问题,连g++都无法安装. 在设置里面: 我以前有一个很不好的习 ...
- 数据流图DFD画法
数据流图(DFD- Data Flow Diagram)让系统分析者弄清楚"做什么"的问题,其重要性就不言而喻了.那么我们怎么画数据流图呢?数据流图与系统流程图又有什么区别呢? 步 ...
- 7 HandlerSet 处理程序链表类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 my.oschina.net/oloroso Handler ...
- IOS路线图
存档,存档...
- PhpExcel笔记,phpExcel中文帮助手册
下面是总结的几个使用方法 include 'PHPExcel.php'; include 'PHPExcel/Writer/Excel2007.php'; //或者include 'PHPExcel/ ...
- EOS/普元:概述:中国IT业的悲哀
公司引入了普元的EOS作为公司的基础架构平台,今后的所有项目将逐步向EOS的迁移,但对EOS的研究又让我不得不说出以下话: 1.EOS确实够简单,但未免简单过了头:从语言层面看EOS 因为EOS将成为 ...
- Javascript——Context和Scope的一些学习总结
1.1.1 摘要 在我们学习Javascript过程中,常常会遇到作用域(Scope)和执行上下文(Context)等概念.其中,执行上下文与this关键字的关系密切. 有面向对象编程经验的各位,对于 ...
- jQuery获取循环中的选中单选按钮radio的值
1.<input type="radio" name="testradio" value="jquery获取radio的值" /> ...
- MongoDB 3.0 新特性【转】
本文来自:http://www.open-open.com/lib/view/open1427078982824.html#_label3 更多信息见官网: http://docs.mongodb.o ...
- ubuntu apc 安装
在ubuntu下安装APC,只需要两条命令,便可将APC和php绑一起. 安装代码: sudo apt-get install -y apache2-prefork-dev ...