Silverlight 结合WCF Duplex Service聊天程序出炉

翻译了 利用 WCF duplex Service 【推送】数据到Siliverlight客户端 的双向通讯例子 收益菲浅, 终于通讯真正做起来了, 刚做好的聊天程序, 后面再补充笔记, 把一些关键问题解决调, 在优化一下.

访问地址: http://www.shareach.com:81/chat

代码下载:http://www.cnblogs.com/yinpengxiang/archive/2009/03/30/1424724.html

以前js版本的: http://www.shareach.com/chat.aspx对应

看了一周的WCF终于有点成果了. 服务端参考了MSDN的这个文章, 客户端参考了MSDN这个文章

看大家登录后测试情况, 这个 双向通讯还是不稳定, 经常有js错误出现,但是不影响正常使用

后续计划:

  • 做公聊的聊天室,现在只有私聊的
  • 完成登录状态即时更新, 现在人家走了一年也不知道
  • 把前面测试的上传功能结合进来
  • 想做一个相册

这么多功能先想想,不知道要到猴年马月搞定

遇到的问题/原因和解决办法吧

1.PollingDuplexHttpBinding.ReceiveTimeout 对应的超时问题 和 这个问题发现后的代码修改方式

这个问题用作IM通讯项目里可能会碰到, 这个属性是针对监听超时, MSDN上描述是”Gets or sets the interval of time that a connection can remain inactive, during which no application messages are received, before it is dropped.” 我开始一度以为,这个是针对整个通道的, 所以一直没有搞明白消息收发仍在正常继续,但又会有超时报错, 经过几天的反复验证,终于发现问题原因和症结了. 我出的错误信息如下:CompleteReceive:Receive on local address http://docs.oasis-open.org/ws-rx/wsmc/200702/anonymous?id=ce16853b-f9cb-47e8-b812-3ea66bda0c45 timed out after 00:01:30. The time allotted to this operation may have been a portion of a longer timeout.这是一个普通的超时错误, 这个错误不是针对通道的, 而是对每个异步监听的错误, 我把我错误原因描述一下, 但是没有想好解决方法.

这个错误是我启动了很多异步监听(不是一个), 我是抄MSDN上的例子. 每次发送消息后我都会调用LoopRecive等消息,然后消息接受完了以后我还调用LoopRecive等消息. 有很多这个监听轮询, 导致超时的.  MSDN上的例子的void CompleteOpenChannel(IAsyncResult result)调用了ReceiveLoop(channel); void CompleteReceive(IAsyncResult result)里面有调用了 ReceiveLoop(channel); 他这个是同步方式在循环发送信息,所以不会出超时异常,我把 SendMessage做了一个消息缓冲池, 每次有消息我就批量的发出去了 而且都调用ReceiveLoop,导致很多监听等待. 主要是例子里面所有的通讯都是顺序的, 但是真实使用的时候不可能这样完全顺序的. 有可能几个消息同时到达客户端, 为了保证消息正常到达,我又有回复机制,这就导致又有RecieveLoop循环,呵呵恶性循环. 还没想到好办法,只是把他try catch调了.

其实我觉得这是一个好处,反正都是异步监听,异步发送,不会影响到通道, 所以我把代码做了修改, 把消息池都去掉了, 呵呵, 看下面:

MSDN相关代码

MSDN相关代码

改了一下流程和发送方式, 去掉了前面加的消息发送池, 既然超时只是针对每次监听回调, 那么我可以怎么发消息都没事了, 也就是连接完成后,我把Channel提出来了, 把发送功能(SendMessage)单独的抛出来了, 以后就一直用它好了,除非通道异常了, 至于通道异常不是这个主题了

我的代码

面的代码中,我可以任意的地方调用SendMessage, 这样就封装成了一个只有几个口的通讯类了, 其它都用了异常属性方法回调, 比较懒, 都是同步调用的,没有用异步方式. 那么那个异常就让他异常去吧, 反正不影响我通讯. 除非后面有好的解决方法.

还有一个就是那个SendMessageState类, 为了在异步发送完成后, 如果出错,知道原始消息是什么了, 但是有个问题就是站着内存, 不过消息不大,呵呵.

2. 异步调用,其它线程访问UI

前面好多地方为了使Silverlight不出错, 都加了Try Catch了, 也没处理(习惯不好,为了快速验证学过的东西), 而且很多回调都是同步的, 在界面上都没有看到错误在哪, 经常出了莫名奇妙的问题, 后来发现很多是因为通道接收到的消息都是uiThread.Post()方法出来的,导致了这个冲突, 后来做了那个调试日志才发现的. 置于怎么访问更新和处理UI看Silverlight中 非UI线程更新UI 的几种方法, 这和WinForm有点类似.

3.全屏模式下键盘无效了

这个问题比较恶心, 我感觉应该是个开关, 微软解释是什么操作安全问题, 全屏不让随便碰屏幕什么的. 如果是开关多好, 开始全屏感觉慢爽的. 发现全屏不能输入, 就不爽了.

4.IE 8

Ie 8 从Beta 开始我就安装了一次,为了那个Dev tool(和firebug类似), 发现不好用, RC的时候又是装了卸了, 正式版还是一样, SL在上面好多问题(是一个在聊天室告诉我的), 包括cnblog版面都是不正常, 又卸了. 这个问题应该不是这个里面的问题, 罗列一下吧.

5.客户端退出让Service即时知道

退出或者异常退出,还没找到办法及时让Service监测到,只有等待session过期才能检测到, 只能把session值设置小一点. 不知道有没有其它办法, 让Service快速知道客户端断了.

 

总的感觉, WCF 非常强大, Silverlight结合WCF做RIA应用觉得比Flash强, 那个SmartFoxServer好难用啊, 而且那个代码太难受.

上次看了CodePlex上的一个开源代码, 上传大文件的, 我上传了7G还没死, 后来不敢继续了, 我把他改了一下上传照片, 网址是 http://www.shareach.com:81/upload, 客户端就处理图片,很爽.

 

后面还要继续研究WCF其它的东西. good good study, day day up.

posted @ 2009-03-23 00:18  shareach  阅读(6346)  评论(23编辑  收藏  举报