tcp wcf
来源:互联网 发布:java hello world 代码 编辑:程序博客网 时间:2024/06/01 10:46
Wcf tcp
我们利用wcf和tcp做一个qq实时在线聊天
步骤:1:上线和我们的下线功能
2:指定的聊天
3:发送文件和字体颜色
Wcf和tcp的转换:
改配置文件:
我们用控制器启动我们的wcf服务。
` 创建一个主机 绑定我们的服务ServiceHost 用typeof 绑定我们的服务
我们还要写一个事件 就是当通信对象转换到打开的时候我们发生的事件 是为了我们方便知道是否打开了我们的服务器
Opened
然后打开我们的主机 open();
例子:
staticvoid Main(string[] args)
{
using (ServiceHost sh = new ServiceHost(typeof(Service1)))
//这里我们要注意using{}这个方法会销毁我们的程序
//实列化一个服务器 绑定一个接口typeof(接口)
{
sh.Opened += sh_Opened;
//打开
sh.Open();
//暂停不让服务销毁
Console.ReadLine();
}
}
static void sh_Opened(object sender, EventArgs e)
{
Console.WriteLine("服务已经启动;");
}
让一个服务器有回调方法:
后台:在接口中设置回调协定的类型 CallbackContract =typeof(回调类)
回调类中需要返回答复消息 就要设置IsOneWay=true
前台:用服务点出我们的服务主机 ,如果我们的主机有回调我们要服务实例化我们的回调类 InstanceContext
回调类:我们要实现我们服务的回调 如果我们要传值的话我们重构传值
例子:
后台:
接口
[ServiceContract(CallbackContract=typeof(IQQlogin_callback))]
回调接口
[OperationContract(IsOneWay =true)]
void onlines(users user);
前台:
//这里我们把本页面给传入过去
InstanceContextic = new InstanceContext(new callback_QQ(this));
// QQ_Service是我们的服务名称
QQ_Service.QQloginServiceClientlsqq = new QQ_Service.QQloginServiceClient(ic);
回调类:
public class callback_QQ : QQ_ .IQQloginServiceCallback
{
public QQ _qq;
public callback_QQ(QQ qq)
{
this._qq =qq;
}
public void onlines(QQ_Service.usersuser)
{
}
public void offlines(stringQQ_numer)
{
}
public void sendmess_callback(QQ_Service.DTO_xiaoxixiaoxi)
{
}
}
1:上线和下线
思路:用户登录访问数据库,登录成功就记录我们用户和用户通道,
在用我们的回调函数告诉前面登录的人,我们上线了
我们用DTO来存储数 :一个登陆返回信息 ,一个记录我们信息和通道的,用一个键值对来取出我们对应的通道,一个上线的对象
登陆返回的DTO:
public class DTO_QQ_reuslt<T>
{
public int number { get;set; }
public string message { get; set; }
//这个泛型用来记录我们在线的人信息
public T value { get; set; }
}
具体思路就是:我们一个用户一登录 我们就记录他的信息和回调通道 和上线信息
然后在调用我们的上线的回调通道
注意我们这里:就是传值的问题
InstanceContext ic = new InstanceContext(new callback_QQ(this));
这里我们传入了一个本页到我们的回调类
所以以后的传值问题我们都传到我们,这页 然后再传入到我们 的回调类
例子:服务:
public DTO.DTO_QQ_reuslt<DTO_uers>getlogin(stringname, string password)
{
dbEntitiesdb = new dbEntities();
//得到当前的回调函数
IQQlogin_callbackcallback = OperationContext.Current.GetCallbackChannel<IQQlogin_callback>();
//获取当前线程正在关闭的事件
OperationContext.Current.Channel.Closing +=Channel_Closing;
//返回的信息
DTO.DTO_QQ_reuslt<DTO_uers>result = new DTO.DTO_QQ_reuslt<DTO_uers>();
if (string.IsNullOrEmpty(name) ||string.IsNullOrEmpty(password))
{
result.number = 501;
result.message ="账号或者密码为空";
}
users user = db.users.Where(a => a.user_name ==name && a.user_password ==password).FirstOrDefault();
if (user !=null)
{
_number = name;
//得到我们在线人信息
DTO_uersdto = new DTO_uers();
dto.user =user;
dto.online =DTO.DTO_chuanshu.dpdic.Values.Select(a => a.qqusers).ToList();
//记录通道
DTO_QQreacdqqreacd = new DTO_QQreacd();
qqreacd.qqusers =user;
qqreacd.qqcallback =callback;
result.number = 200;
result.message ="登陆成功";
result.value =dto;
//告诉前面的用户我已经登录了
foreach (varitem in DTO.DTO_chuanshu.dpdic.Values)
{
item.qqcallback.onlines(user);
}
//记录用户信息和用户的通道
DTO.DTO_chuanshu.dpdic.Add(name,qqreacd);
}
else
{
result.number = 201;
result.message ="账号或者密码错误";
}
//IQQlogin_callback iqqcallback =OperationContext.Current.GetCallbackChannel<IQQlogin_callback>();
////iqqcallback.login(DTO.DTO_chuanshu.qquers);
return result;
}
void Channel_Closing(object sender, EventArgs e)
{
//先移除自己的qq帐号
DTO_chuanshu.dpdic.Remove(_number);
//传递一个下线的qq帐号
foreach (varitem in DTO.DTO_chuanshu.dpdic.Values)
{
item.qqcallback.offlines(_number);
}
}
发送信息 就和我们的登陆差不多,调用我们的回调通道
我们发送文件和我们的颜色:
发送文件我们用二进制读取,颜色的话我们用ToArgb()把颜色转换成我们的int 类型 然后我们在回调类中用FromArgb()把它弄回来
例子:客户端
public async void send_File()
{
OpenFileDialogofd = new OpenFileDialog();
ofd.ShowDialog();
// MessageBox.Show(ofd.FileName);
if (string.IsNullOrEmpty(ofd.FileName))
{
MessageBox.Show("请选择文件");
return;
}
FileStreamfs = new FileStream(ofd.FileName,FileMode.Open);
long alllength = fs.Length;
var offset = 0; //记录位置
byte[] filebyte = null;
this.progressBar1.Maximum = (int)(fs.Length / 1000);
while (offset !=fs.Length)
{
///这里我们做一个限速传入
if (fs.Length -offset <= 1024 * 100)
{
filebyte = new byte[fs.Length -offset];
}
else
{
filebyte = new byte[1024 * 100];
}
//filebyte = new byte[alllength - offset];
fs.Read(filebyte, 0,filebyte.Length);
sfns = new Send_FileName_Service.Send_FilenameClient();
await sfns.sendfilenameAsync(ofd.SafeFileName,filebyte);
if (jingcheng==0)
{
offset = offset + filebyte.Length;
}
if (jingcheng==-1)
{
offset = 0;
}
this.progressBar1.Value = (offset / 1000);
}
MessageBox.Show(ofd.FileName +"文件传输完成......");
}
服务:
public void sendfilename(stringfilename,byte[] bytes)
{
string path = "e:/" + filename;
fs = new FileStream(path,FileMode.Append);
fs.Write(bytes,0,bytes.Length);
fs.Close();
}
小技巧:如何让一个对象中装入另外一个对象 我们用泛型
键值对中也可以用上我们的linp语句
- tcp wcf
- WCF 配置TCP连接
- WCF 跨域TCP绑定
- WCF net.TCP 小记
- WCF调用TCP 10048错误
- Wcf配置TCP协议小结
- wcf net.tcp 双向通讯
- WCF .net Tcp 错误异常
- WCF net.tcp 消息推送
- [WCF]利用net.tcp傳輸協定來建置WCF Service
- Transfer file with WCF TCP binding.
- wcf 部署在IIS上,tcp.net
- 如何配置net.tcp 的WCF服务
- WCF 采用net.tcp协议实践
- 通过TCP传输方式连接WCF
- iis 上部署tcp的wcf
- 一个完整的Net Tcp WCF配置文件
- WCF 配置节点HTTP与TCP
- 用BASS库重采样音频
- [leetcode]解决Move Zeroes的一点小心得
- Ubuntu下挂载硬盘剩余空间
- 交互式python shell
- 编写一个程序,可以一直接收键盘字符,如果是小写字符就输出对应的大写字符,如果接收的是大写字符,就输出对应的小写字符,如果是数字不输出
- tcp wcf
- ECMAscript5 手册
- 使用cp、mv命令时不询问
- [libxml2]_[C/C++]_[高效输出XML大文件]
- 8属性操作
- art heap创建流程
- 指针数组,数组指针,函数指针,函数指针数组 ,指向函数指针数组的指针
- usaco
- 通过ONOSFW项目让Neutron使用ONOS作为SDN控制器(by quqi99)