博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Silverlight使用socket tcp简单实现聊天室功能
阅读量:5918 次
发布时间:2019-06-19

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

   Silverlight虽然提供了socket功能,但仅仅数据接收和发送的基础功能,你必须还要息制定协议和处理烦脑的粘包问题才能更好地进行信息处理.这里介绍如何通过Beetle.SL这个基于Silverlight socket实现的开源组件如何方便地解决这些问题.下面通过组件在Silverlight下实现一个聊天室程序.聊天室的功能主要是登陆,获取当前其他用户和信息转发.

    首先Beetle.SL是支持通过对象来描述tcp通讯协议,只需简单地实现IMessage接收就可以了.以下是制定信息

public class Register:MsgBase    {        public string Name;        public override void Load(Beetle.BufferReader reader)        {            base.Load(reader);            Name = reader.ReadString();                   }        public override void Save(Beetle.BufferWriter writer)        {            base.Save(writer);            writer.Write(Name);                   }           }

这是用户注册到聊天室信息,还有更多的信息描述最终可以下载项目得到就不一一介绍了.

    消息制定后就要处理tcp连接和接收问题,Beetle.SL封装了一个TcpChannel对象,提供简单的方法事件,如消息接收,消息发送,连接成功和连接断开等.

Beetle.ChannelController.RegisterHandler(this);            mChannel = new Beetle.TcpChannel(new HeadSizePackage());            new Beetle.ChannelController(mChannel);            mChannel.Connected += OnConnected;            mChannel.Disposed += OnDisposed;            mChannel.Error += OnError;

ChannelController是一个消息控制器,它的主要功能是自动把接收的消息路由到有相关消息类型的方法上,可以让不需要判断消息类型执行不同方法的过程.在创建一个TcpChannel的时候指定一个分析器即可,这里是一个消息头4个字节描述大小的分析方式;组件还提供基于结束符的分析器详细可以查看Beetle.SL的代码.信道创建后绑定相关事件,由于ChannelController接管了信道所以不需要绑定消息接收事件.

    连接创完成了,现在就看下消息是怎处理的

public void _ReceiveSay(Beetle.TcpChannel channel, Say e)        {            this.Dispatcher.BeginInvoke(() =>            {                addSay(e.Lines, e.User);            });        }        public void _OtherUnRegister(Beetle.TcpChannel channel, UnRegister e)        {            this.Dispatcher.BeginInvoke(() =>            {                ListUsers list = new ListUsers();                mChannel.Send(list);            });        }        public void _OthreRegister(Beetle.TcpChannel channel, OnRegister e)        {            this.Dispatcher.BeginInvoke(() =>            {                if (!lstNames.Items.Contains(e.User))                {                    lstNames.Items.Add(e.User);                }            });        }        public void _OnLogin(Beetle.TcpChannel channel, RegisterResponse e)        {            ListUsers list = new ListUsers();            mChannel.Send(list);            this.Dispatcher.BeginInvoke(() =>            {                cmdSend.IsEnabled = true;                cmdConnect.IsEnabled = false;            });        }        public void _OnList(Beetle.TcpChannel channel, ListUsersResponse e)        {            this.Dispatcher.BeginInvoke(() =>            {                lstNames.Items.Clear();                foreach (UserInfo item in e.Users)                {                    lstNames.Items.Add(item);                }            });        }

看上去代码是不是很少,消息处理基本就是这些了.你不需要数据包分析,不需消息判断处理.这些就是Beetle.SL所做的事情.

    通讯和输出的代码虽然已经完成,但还有些重要的事情.讲解之前先看下效果图

用过Silverlight的RichTextBox控件的朋友应该知道RichTextBox获取xaml属性有些元素是无法获取的,所以不得不自己封装一下.针对这些信息的传输制定一个转换对象.

public class Line:Beetle.IMessage    {        public IList
Elements = new List
(); public void Load(Beetle.BufferReader reader) { Elements = reader.ReadObjects
(); } public void Save(Beetle.BufferWriter writer) { writer.Write(Elements); } } public class Element:Beetle.IMessage { public const int TEXT = 1; public const int IMAGE = 2; public const int None = 0; public string Text; public string URI; public byte[] Data; public int EType; public void Load(Beetle.BufferReader reader) { EType = reader.ReadInt32(); Text = reader.ReadString(); URI = reader.ReadString(); Data = reader.ReadByteArray(); } public void Save(Beetle.BufferWriter writer) { writer.Write(EType); writer.Write(Text); writer.Write(URI); writer.Write(Data); } }

以上制定了两种对象来处理,一个是描述行,一个是描述行里面的元素.元素这里并没有所有情况都处理,只是简单地处理TEXT和IMAGE两个元素.在一个简单的聊天室来说够用了.如果实现需要估计要重新设计和定义了.如果要传本机图象那就要多写些代码了,原理很简单imagesource和byte[]转换 

    传输的结构制定了就是针对RichTextBox的内容实现一个简单转换方法.

public static IList
GetLines(BlockCollection bc) { List
result = new List
(); Element el; Line line; foreach (Paragraph item in bc) { line = new Line(); result.Add(line); foreach(Inline il in item.Inlines) { if (il is Run) { el = new Element(); el.EType = Element.TEXT; el.Text = ((Run)il).Text; line.Elements.Add(el); } else if( il is InlineUIContainer) { InlineUIContainer iui =(InlineUIContainer)il; if (iui.Child != null && iui.Child is Image) { Image img = (Image)iui.Child; if (img.Source is BitmapImage) { el = new Element(); el.EType = Element.IMAGE; el.URI = ((BitmapImage)img.Source).UriSource.ToString(); line.Elements.Add(el); } } } else{ } } } return result; } public static void SetLines(BlockCollection bc, IList
lines) { foreach (Line item in lines) { Paragraph p = new Paragraph(); bc.Add(p); Run sp = new Run(); sp.Text = "\t"; p.Inlines.Add(sp); foreach (Element e in item.Elements) { if (e.EType == Element.TEXT) { Run run = new Run(); run.Text = e.Text; p.Inlines.Add(run); } else if (e.EType == Element.IMAGE) { InlineUIContainer iui = new InlineUIContainer(); Image img = new Image(); iui.Child = img; img.Height = 24; img.Width = 24; var uri = new Uri(new Uri( string.Format("{0}://{1}:{2}/" ,App.Current.Host.Source.Scheme,App.Current.Host.Source.Host,App.Current.Host.Source.Port)), e.URI); img.Source = new BitmapImage(uri); p.Inlines.Add(iui); } else { } } } }

    到这里这个Silverlight的简单聊天室就完成了.想更详细地了解实现过程到获取Beetle.SL源和项目代码.

    demo:

 

转载地址:http://tlfvx.baihongyu.com/

你可能感兴趣的文章
十二款用于自主云评测的开源工具
查看>>
Android Studio第二十期 - 识别Recorder声纹显示水波泡泡效果
查看>>
使用systemtap抓取ssh登录的用户名和密码
查看>>
为什么你总是拿不到高薪?
查看>>
SCCM 2012系列15 操作系统播发④
查看>>
Formik官方应用案例解析( 五)React Native
查看>>
MySQL管理之道:第二版上市!China-Pub首发
查看>>
从云原生看企业云的未来
查看>>
Shell图形化监控网络流量
查看>>
通过两个案例初步了解Linux下selinux的安全机制工作机制
查看>>
京东VS天猫 双十一猫狗大战再升级
查看>>
OSSIM下ISO 27001信息安全管理系统认证
查看>>
京东商城用户资料完全泄露
查看>>
关于贵和源(杜树杰)送开光佛珠欺诈粉丝一事重要说明
查看>>
使用Python的twisted和socket模块实现端口的负载分发
查看>>
Errno 9: Bad file descriptor in python socket错误处理
查看>>
JMX rmi的一些问题
查看>>
ASP.Net中防止页面刷新重复提交的几种方法
查看>>
翻译:Knockout 快速上手 - 5: 你需要知道的顶级特性 续
查看>>
iOS多线程之NSOperation和NSOperationQueue的使用
查看>>